package api

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/internal/admin/services"
	"TaskAssignmentSystem/internal/pkg/code"
	"TaskAssignmentSystem/internal/pkg/middleware/handler"
	"TaskAssignmentSystem/internal/pkg/middleware/mysqlhandler"
	"TaskAssignmentSystem/internal/pkg/modelbase"
	"TaskAssignmentSystem/pkg/db/mysql"
	"TaskAssignmentSystem/pkg/db/redis"
	"TaskAssignmentSystem/pkg/oss"
	"TaskAssignmentSystem/pkg/timehandler"
	"TaskAssignmentSystem/pkg/utils"
	"errors"
	"fmt"
	"github.com/go-the-way/exl"
	"github.com/kataras/iris/v12"
	"github.com/tealeg/xlsx"
	"github.com/wxnacy/wgo/arrays"
	"github.com/xuri/excelize/v2"
	"gorm.io/gorm"
	"io/ioutil"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"
)

const (
	ENUM_TYPE_NORMAL = 0 //答主项目
	ENUM_TYPE_ONE    = 1 //一审项目
	ENUM_TYPE_TWO    = 2 //二审项目
)

// @Summary 批量导入题目
// @Description 批量导入题目
// @Tags 项目
// @Accept multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量导入题目参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/imports/{project_id} [post]
func NewExcelTopicImportsHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	projectDO := &dao.SystemProject{}
	if err := mysql.GetDB().Where("project_id = ?", projectId).First(projectDO).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	// 题目类型
	enumType := projectDO.EnumType
	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	var topicServe services.TopicService
	if topicConfigurations, err := exl.Read[*modelbase.TopicConfiguration](file); err != nil {
		fmt.Println("read excel err:" + err.Error())
	} else {
		fmt.Printf("read excel TopicConfiguration num: %d\n", len(topicConfigurations))
		var configuration = make(map[string][]modelbase.TopicConfiguration)
		for i, model := range topicConfigurations {
			//从第二行开始读取
			if i == 0 {
				continue
			}
			// key -> 题目批次，value -> 题目配置（多个配置）
			configuration[model.Batch] = append(configuration[model.Batch], *model)
		}

		if len(configuration) == 0 {
			utils.ResponseServerError(errors.New("题目配置不能为空"))
			return
		} else {
			file, _ := handle.Open()
			defer file.Close()
			if systemTopicExecls, err := exl.Read[*modelbase.SystemTopicExecl](file); err != nil {
				fmt.Println("read excel err:" + err.Error())
			} else {
				for i, topic := range systemTopicExecls {
					//从第二行开始读取
					if i == 0 {
						continue
					}
					//题目ID为空就跳过
					if utils.StringIsEmpty(topic.TopicId) {
						continue
					}
					var topicObj dao.SystemTopic
					topicObj.EnumType = enumType
					topicObj.ProjectId = projectId
					topicObj.SN = topic.SN
					topicObj.BatchId = topic.BatchId

					topicObj.TopicId = topic.TopicId
					topicObj.Title = topic.Title
					// I 列：题目检索标签
					if topic.Labels != "" {
						for _, item := range strings.Split(topic.Labels, "；") {
							topicObj.Labels = append(topicObj.Labels, item)
						}
					}
					if topic.EffectiveTime != "" {
						topicObj.EffectiveTime, _ = time.ParseInLocation(timehandler.FormatLayoutTime, topic.EffectiveTime, time.Local)

					}
					if topic.EndDateTime != "" {
						topicObj.EndDateTime, _ = time.ParseInLocation(timehandler.FormatLayoutTime, topic.EndDateTime, time.Local)
					}
					topicObj.GiveUpNumber = topic.GiveUpNumber
					if topic.TopicNoteStr != "" {
						for s1, s2 := range strings.Split(topic.TopicNoteStr, "；") {
							topicObj.TopicNote = append(topicObj.TopicNote, modelbase.TopicNote{
								SN:      s1 + 1,
								TopicId: topic.TopicId,
								Content: s2,
							})
						}
					}
					// 题目配置
					if _, ok := configuration[topicObj.BatchId]; ok {
						for _, topicConfiguration := range configuration[topicObj.BatchId] {
							topicConfiguration.TopicId = topicObj.TopicId
							topicObj.TopicConfiguration = append(topicObj.TopicConfiguration, topicConfiguration)
						}
					}
					// MySQL 5.7 以上版本不允许插入无效日期
					topicObj.FinishTime = time.Now()
					// 题目表唯一索引 (`project_id`,`topic_id`)
					topicServe.NewBatchInsertTopic(topicObj)
				}
				redis.RedisGClient.SetNX("TaskTopicStart", "value", time.Duration(1)*time.Second)
				ctx.JSON(utils.ResponseOK())
				return
			}
		}
	}
}

// @Summary 批量导入题目
// @Description 批量导入题目
// @Tags 项目
// @Accept multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量导入题目参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/imports/{project_id} [post]
func ExcelTopicImportsHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	projectDO := &dao.SystemProject{}
	if err := mysql.GetDB().Where("project_id = ?", projectId).First(projectDO).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	// 题目类型
	enumType := projectDO.EnumType

	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		fmt.Println(err)
	}
	xlFile, err := xlsx.OpenBinary(fileByte)
	if err != nil {
		fmt.Printf("open failed: %s\n", err)
	}
	titles := []string{"每题序号", "题目批次", "题目ID", "题目名字", "题目检索标签(如不填写，则默认搜可搜素题目名字)", "题目生效时间", "截止时间", "被放弃多少次之后，系统自动作废该题目", "备注（使“；”分隔符）"}
	sheet2titles := []string{"题目批次", "答题类型（0：文本框；1：上传文件；2：复合框，既可以上传文件也可以写文字+图片）", "表单标题", "提示文字（如有超链接，也可以点击跳转）", "是否是必填1（0：是；1：否）", "上传校验（1：开启校验；0：取消校验）", "上传文件小于等于（单位MB）（如果不填则无限制）"}
	var topicServe services.TopicService
	var res ImportsResponse

	if len(xlFile.Sheets) < 2 {
		ctx.JSON(utils.ResponseError{Code: iris.StatusBadRequest, Message: "上传文件格式错误"})
	}
	var configuration = make(map[string][]modelbase.TopicConfiguration)

	// 处理题目配置
	for i, sh := range xlFile.Sheets {
		if i == 0 {
			continue
		}
		if i == 1 {
			//sheet 2的数据处理，处理题目的配置数据
			for i, row := range sh.Rows {
				var errListLength = len(res.ErrList)
				//判断excel格式对不对
				if i == 0 {
					for j, title := range sheet2titles {
						if row.Cells[j].String() != title {
							ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
							return
						}
					}
				}
				//从第三行开始
				if i >= 2 {
					var rowsList []string
					var topicConfigurationObj modelbase.TopicConfiguration
					var row_data string
					for j, cell := range row.Cells {
						text := strings.TrimSpace(cell.String())
						row_data += text
						if text == "" && j < len(sheet2titles) {
							if j != 6 {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sh.Name,
									Number: i + 1,
									Cell:   j + 1,
									Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, sheet2titles[j]),
								})
							}

						}
						rowsList = append(rowsList, text)
					}
					if strings.TrimSpace(row_data) == "" {
						//res.TotalRows -= 1
						break
					}
					/*
						if len(rowsList) < len(sheet2titles) {
							for k := len(rowsList); k < len(sheet2titles); k++ {
								res.ErrList = append(res.ErrList, code.ImportError{
									Number: i + 1,
									Cell:   k + 1,
									Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, sheet2titles[k]),
								})
							}
						}
					*/
					if rowsList[1] != "" {
						topicConfigurationObj.AnswerType, err = strconv.Atoi(rowsList[1])
						if err != nil {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   1 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效", i+1, sheet2titles[1]),
							})
						}
						if arrays.Contains([]int{0, 1, 2}, topicConfigurationObj.AnswerType) == -1 {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   1 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[1]),
							})
						}
					}
					topicConfigurationObj.Title = rowsList[2]
					topicConfigurationObj.Tooltip = rowsList[3]
					if rowsList[4] != "" {
						topicConfigurationObj.Required, err = strconv.Atoi(rowsList[4])
						if arrays.Contains([]int{0, 1}, topicConfigurationObj.Required) == -1 {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   4 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[4]),
							})
						}
						if err != nil {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   4 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[4]),
							})
						}
					}
					if rowsList[5] != "" {
						topicConfigurationObj.IsCheck, err = strconv.Atoi(rowsList[5])
						if arrays.Contains([]int{0, 1}, topicConfigurationObj.IsCheck) == -1 {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   5 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[5]),
							})
						}
						if err != nil {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   5 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[5]),
							})
						}
					}
					if len(rowsList) == 7 && rowsList[6] != "" {
						topicConfigurationObj.FileSizeLimit, err = strconv.Atoi(rowsList[6])
						if err != nil {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sh.Name,
								Number: i + 1,
								Cell:   6 + 1,
								Reason: fmt.Sprintf("第%d行字段%s的值非有效值", i+1, sheet2titles[6]),
							})
						}
					}

					if len(res.ErrList) > errListLength {
						res.FailRows += 1
						continue
					}
					// key -> 题目批次，value -> 题目配置（多个配置）
					configuration[rowsList[0]] = append(configuration[rowsList[0]], topicConfigurationObj)
				}
			}
		}
	}
	if len(configuration) == 0 {
		res.ErrList = append(res.ErrList, code.ImportError{
			Reason: fmt.Sprintf("题目配置不能为空"),
		})
		res.FailRows = 1
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
		return
	} else {

		var cnm = runtime.NumCPU() - 1
		runtime.GOMAXPROCS(cnm)
		wg := sync.WaitGroup{}
		//导入题目
		for s, sheet := range xlFile.Sheets {
			if s == 0 {
				for i, row := range sheet.Rows {
					var errListLength = len(res.ErrList)
					//判断excel格式对不对
					if i == 0 {
						for j, title := range titles {
							if row.Cells[j].String() != title {
								ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
								return
							}
						}
					}
					//从第三行开始
					if i >= 2 {

						res.TotalRows += 1
						//fmt.Println(res.TotalRows)
						var rowsList []string
						var topicObj dao.SystemTopic
						var row_data string
						for j, cell := range row.Cells {
							text := strings.TrimSpace(cell.String())
							row_data += text
							if text == "" && j < len(titles) {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Cell:   j + 1,
									Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[j]),
								})
							}
							rowsList = append(rowsList, text)
						}
						if strings.TrimSpace(row_data) == "" {
							//fmt.Println("res.TotalRows", res.TotalRows)
							res.TotalRows += -1
							//fmt.Println("res.TotalRows", res.TotalRows)
							break
						}

						if len(rowsList) < len(titles) {
							for k := len(rowsList); k < len(titles); k++ {
								res.ErrList = append(res.ErrList, code.ImportError{
									Number: i + 1,
									Cell:   k + 1,
									Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[k]),
								})
							}
							res.FailRows += 1
							continue
						}
						topicObj.EnumType = enumType
						topicObj.ProjectId = projectId
						if rowsList[0] != "" {
							topicObj.SN, err = strconv.Atoi(rowsList[0])
							if err != nil {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Cell:   0 + 1,
									Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1]),
								})
							}
						}

						topicObj.BatchId = rowsList[1]

						topicObj.TopicId = rowsList[2]
						topicObj.Title = rowsList[3]
						// I 列：题目检索标签
						if rowsList[4] != "" {
							for _, item := range strings.Split(rowsList[4], "；") {
								topicObj.Labels = append(topicObj.Labels, item)
							}
						}
						if rowsList[5] != "" {
							topicObj.EffectiveTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[5], time.Local)
							if err != nil {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Cell:   5 + 1,
									Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1]),
								})
							}
						}
						if rowsList[6] != "" {
							topicObj.EndDateTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[6], time.Local)
							if err != nil {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Cell:   6 + 1,
									Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1]),
								})
							}
						}
						if rowsList[7] != "" {
							topicObj.GiveUpNumber, err = strconv.Atoi(rowsList[7])
							if err != nil {
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Cell:   7 + 1,
									Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1]),
								})
							}
						}
						if rowsList[8] != "" {
							for s1, s2 := range strings.Split(rowsList[8], "；") {
								topicObj.TopicNote = append(topicObj.TopicNote, modelbase.TopicNote{
									SN:      s1 + 1,
									TopicId: rowsList[1],
									Content: s2,
								})
							}
						}
						if len(res.ErrList) > errListLength {
							res.FailRows += 1
						}
						// 题目配置
						if _, ok := configuration[topicObj.BatchId]; ok {
							for _, topicConfiguration := range configuration[topicObj.BatchId] {
								topicConfiguration.TopicId = topicObj.TopicId
								topicObj.TopicConfiguration = append(topicObj.TopicConfiguration, topicConfiguration)
							}
						}
						// MySQL 5.7 以上版本不允许插入无效日期
						topicObj.FinishTime = time.Now()
						wg.Add(1)
						var ch = make(chan error)
						// 题目表唯一索引 (`project_id`,`topic_id`)
						go topicServe.BatchInsertTopic(ch, topicObj, &wg)
						chErr := <-ch
						defer close(ch)
						if chErr != nil {
							switch mysqlhandler.MysqlErrCode(chErr) {
							case mysqlhandler.ErrDuplicateEntryCode:
								fmt.Println(chErr)
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Reason: "该条数据已经存在",
								})
							default:
								res.ErrList = append(res.ErrList, code.ImportError{
									Sheet:  sheet.Name,
									Number: i + 1,
									Reason: chErr.Error(),
								})
							}
							res.FailRows += 1
						} else {
							res.SuccessRows += 1
						}
					}
				}
				wg.Wait()
			}
		}
		redis.RedisGClient.SetNX("TaskTopicStart", "value", time.Duration(1)*time.Second)
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
		return
	}
}

type TopicListRequest struct {
	Page          int64    `json:"page"`
	PageSize      int64    `json:"page_size"`
	Title         string   `json:"title"` //题目名称
	ProjectId     string   `json:"project_id"`
	TopicId       string   `json:"topic_id"`       //题目ID
	Status        int      `json:"status"`         //状态 0 未生效 1已完成 2 已领取 3指派中 4返修中 5 闲置中 6 已作废
	EffectiveTime []string `json:"effective_time"` //题目生效时间
	EndDateTime   []string `json:"end_date_time"`  // 截止时间
	FinishTime    []string `json:"finish_time"`    //完成时间
	TeamNumber    string   `json:"team_number"`    //团队编号
	NickName      string   `json:"nick_name"`      //用户昵称
	RealName      string   `json:"real_name"`      // 姓名
	UserId        string   `json:"user_id"`        //用户Id
	AnswerStatus  string   `json:"answer_status"`  //答主题目状态
	OneStatus     string   `json:"one_status"`     //一审题目状态
}

// @Summary 题目列表
// @Description 题目列表
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body TopicListRequest true "题目列表参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/list [post]
func TopicListHandler(ctx iris.Context) {
	var RequestParams TopicListRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	type SystemTopic struct {
		dao.SystemTopic
		TeamNumber     string    `json:"team_number"`                //团队编号
		UserId         string    `json:"user_id" gorm:"uniqueIndex"` //用户Id
		RealName       string    `json:"real_name"`                  // 姓名
		Phone          string    `json:"phone"`                      //手机号
		NickName       string    `json:"nick_name"`                  //用户昵称
		Email          string    `json:"email"`                      //邮箱
		AnswerStatus   string    `json:"answer_status"`              //答主题目状态
		RejectTime     time.Time `json:"reject_time"`                //驳回时间
		OneStatus      string    `json:"one_status"`                 //一审题目状态
		OneAuditStatus string    `json:"one_audit_status"`           //一审审核状态
		TwoStatus      string    `json:"two_status"`                 //二审题目状态
		TwoAuditStatus string    `json:"two_audit_status"`           //二审审核状态
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var common dao.Common[dao.SystemAdmin]
	admin, _ := common.First(map[string]interface{}{"id": claims.Id})

	var topicServe services.CommonService[SystemTopic]
	topicServe.Page = RequestParams.Page
	topicServe.PageSize = RequestParams.PageSize
	topicServe.Query = map[string]interface{}{}

	//处理团队权限
	var team_numbers []string
	//if claims.Type == 2 {
	if len(admin.TeamPermissions) > 0 {
		for _, team := range admin.TeamPermissions {
			team_numbers = append(team_numbers, team)
		}
	}
	//}

	var projectServe services.CommonService[dao.SystemProject]
	projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
	field := ""
	if project, err := projectServe.First(); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		//一审项目
		if project.EnumType == ENUM_TYPE_ONE {
			//如果有二审
			if utils.StringIsNotEmpty(project.FinalProjectId) {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status,d.status two_status,d.audit_status two_audit_status")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
			} else {
				//如果没有二审只查答主的
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
			}
			if RequestParams.Status != -1 {
				//一审通过
				if RequestParams.Status == 1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status != 0", RequestParams.Status))
				} else if RequestParams.Status == 8 {
					//一审拒绝
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
				} else {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
				}
			}
		} else if project.EnumType == ENUM_TYPE_TWO {
			//二审项目
			field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,d.`status` one_status,d.audit_status one_audit_status,tas_system_topic.`status` two_status,tas_system_topic.audit_status two_audit_status")
			topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
			topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
			topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.AuditProjectId))
			if RequestParams.Status != -1 {
				//二审通过
				if RequestParams.Status == 1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status = 2", RequestParams.Status))
				} else if RequestParams.Status == 8 {
					//二审拒绝
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
				} else {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
				}
			}
		} else {
			//答主项目
			//如果有一审
			if utils.StringIsNotEmpty(project.AuditProjectId) {
				//如果有二审
				if utils.StringIsNotEmpty(project.AuditProjectId) {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status,d.`status` two_status,d.audit_status two_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
				} else {
					//没有二审只有一审
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
				}
			} else {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
			}
			if RequestParams.Status != -1 {
				if RequestParams.Status == 1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.reject_time < now()", RequestParams.Status))
				} else if RequestParams.Status == 4 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
				} else {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
				}
			}
		}
	}
	if len(team_numbers) > 0 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
	}
	if RequestParams.Title != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
	}
	if RequestParams.TopicId != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
	}
	if RequestParams.TeamNumber != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
	}
	if RequestParams.NickName != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
	}
	if RequestParams.RealName != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
	}
	if RequestParams.UserId != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
	}
	topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
	if len(RequestParams.EffectiveTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
	}
	if len(RequestParams.EndDateTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
	}
	if len(RequestParams.FinishTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
	}
	topicServe.Order = "tas_system_topic.sn"
	topicServe.SelectField = &field

	if res, err := topicServe.SelectList(); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"count": res.Total, "list": res.Data}})
		return
	}
}

type DeleteTopicRequest struct {
	Id uint `json:"id" validate:"required"`
}

// @Summary 删除题目
// @Description 删除题目
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body DeleteTopicRequest true "删除题目参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/del [post]
func DeleteTopicHandler(ctx iris.Context) {
	var RequestParams DeleteTopicRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	/*if claims.Type == 2 {
		ctx.JSON(utils.ResponseError{Code: 403, Message: "权限不够"})
		return
	}*/
	var topicServe services.TopicService
	if err := topicServe.RemoveById(RequestParams.Id); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type ChangeTopicStatusRequest struct {
	Id     uint `json:"id" validate:"required"`
	Status int  `json:"status"`
}

// @Summary 更新题目状态
// @Description 更新题目状态 作废、归库、返修
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body ChangeTopicStatusRequest true "更新题目状态参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/change_status [post]
func ChangeTopicStatusHandler(ctx iris.Context) {
	var RequestParams ChangeTopicStatusRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var topicServe services.TopicService
	if err := topicServe.ChangeStatus(RequestParams.Id, RequestParams.Status); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type NewTopicConfigurationRequest struct {
	Title         string `json:"title"`           //表单标题
	AnswerType    int    `json:"answer_type"`     //题目作答类型 0 文本框 1 上传文件
	TopicId       string `json:"topic_id"`        //用户自定义的题目Id
	Required      int    `json:"required"`        //是否必填 0 选填 1必填
	Tooltip       string `json:"tooltip"`         //提示文本
	IsCheck       int    `json:"is_check"`        //上传文件是否校验名称 0不校验 1 校验
	SystemTopicId uint   `json:"system_topic_id"` //关联的题目Id
}

// @Summary 新增题目配置
// @Description 新增题目配置
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body NewTopicConfigurationRequest true "新增题目配置参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/configuration/created [post]
func CreatedTopicConfigurationHandler(ctx iris.Context) {
	var RequestParams NewTopicConfigurationRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var topicServe dao.Common[dao.TopicConfiguration]
	var topicConfiguration dao.TopicConfiguration
	topicConfiguration.TopicId = RequestParams.TopicId
	topicConfiguration.Tooltip = RequestParams.Tooltip
	topicConfiguration.Title = RequestParams.Title
	topicConfiguration.AnswerType = RequestParams.AnswerType
	topicConfiguration.IsCheck = RequestParams.IsCheck
	topicConfiguration.Required = RequestParams.Required
	topicConfiguration.SystemTopicId = RequestParams.SystemTopicId
	if err := topicServe.CreateOne(topicConfiguration).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type EditTopicConfigurationRequest struct {
	Id         uint   `json:"id" validate:"required"`
	Title      string `json:"title"`       //表单标题
	AnswerType int    `json:"answer_type"` //题目作答类型 0 文本框 1 上传文件
	Required   int    `json:"required"`    //是否必填 1 选填 0必填
	Tooltip    string `json:"tooltip"`     //提示文本
	IsCheck    int    `json:"is_check"`    //上传文件是否校验名称 0不校验 1 校验
}

// @Summary 编辑题目配置
// @Description 编辑题目配置
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body EditTopicConfigurationRequest true "编辑题目配置参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/configuration/edit [post]
func EditTopicConfigurationHandler(ctx iris.Context) {
	var RequestParams EditTopicConfigurationRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var topicServe dao.Common[dao.TopicConfiguration]
	topicServe.Query = map[string]interface{}{"id": RequestParams.Id}
	set := make(map[string]interface{})
	set["required"] = RequestParams.Required
	set["title"] = RequestParams.Title
	set["tooltip"] = RequestParams.Tooltip
	set["answer_type"] = RequestParams.AnswerType
	set["is_check"] = RequestParams.IsCheck
	if err := topicServe.Update(set).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type DeleteTopicConfigurationRequest struct {
	Id uint `json:"id" validate:"required"`
}

// @Summary 删除题目配置
// @Description 删除题目配置
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body DeleteTopicConfigurationRequest true "删除题目配置参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/configuration/del [post]
func DeleteTopicConfigurationHandler(ctx iris.Context) {
	var RequestParams DeleteTopicConfigurationRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var topicConfigurationServe dao.Common[dao.TopicConfiguration]
	topicConfigurationServe.Query = map[string]interface{}{"id": RequestParams.Id}
	if err := topicConfigurationServe.RemoveUnscopedWhere(topicConfigurationServe.Query).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type NewTopicNoteRequest struct {
	SN            int    `json:"sn" validate:"required"`              //序号
	SystemTopicId uint   `json:"system_topic_id" validate:"required"` //题目数据库Id
	TopicId       string `json:"topic_id" validate:"required"`        //题目自定义 Id
	Content       string `json:"content" validate:"required"`         //题目备注文本
}

// @Summary 新建题目备注
// @Description 创建一条新的题目备注
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body NewTopicNoteRequest true "新建题目备注参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/note/created [post]
func CreatedTopicNoteHandler(ctx iris.Context) {
	var RequestParams NewTopicNoteRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var common dao.Common[dao.TopicNote]
	var topicNote dao.TopicNote
	topicNote.SystemTopicId = RequestParams.SystemTopicId
	topicNote.TopicId = RequestParams.TopicId
	topicNote.SN = RequestParams.SN
	topicNote.Content = RequestParams.Content
	if err := common.CreateOne(topicNote).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type EditTopicNoteRequest struct {
	Id      uint   `json:"id" validate:"required"`
	SN      int    `json:"sn" validate:"required"`      //序号
	Content string `json:"content" validate:"required"` //题目备注文本
}

// @Summary 编辑题目备注
// @Description 编辑题目备注
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body EditTopicNoteRequest true "编辑题目备注参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/note/edit [post]
func EditTopicNoteHandler(ctx iris.Context) {
	var RequestParams EditTopicNoteRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var common dao.Common[dao.TopicNote]
	common.Query = map[string]interface{}{"id": RequestParams.Id}
	set := make(map[string]interface{})
	set["sn"] = RequestParams.SN
	set["content"] = RequestParams.Content
	if err := common.Update(set).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type DeleteTopicNoteRequest struct {
	Id uint `json:"id" validate:"required"`
}

// @Summary 删除题目备注
// @Description 删除题目备注
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body DeleteTopicNoteRequest true "删除题目备注参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/note/del [post]
func DeleteTopicNoteHandler(ctx iris.Context) {
	var RequestParams DeleteTopicNoteRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var topicNoteServe dao.Common[dao.TopicNote]
	topicNoteServe.Query = map[string]interface{}{"id": RequestParams.Id}
	if err := topicNoteServe.RemoveUnscopedWhere(topicNoteServe.Query).Error; err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

// @Summary 题目详情
// @Description 题目详情
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param id path uint true "题目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/{id} [get]
func TopicDetail(ctx iris.Context) {
	topicId, err := ctx.Params().GetUint("id")
	if err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var common dao.Common[dao.SystemTopic]
	common.Query = map[string]interface{}{"id": topicId}
	if systemTopic, err := common.First(common.Query); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		var userIds []string
		for _, record := range systemTopic.TopicUserRecord {
			userIds = append(userIds, record.UserId)
		}
		type TopicUserRecord struct {
			RealName      string    `json:"real_name"`
			CreatedAt     time.Time `json:"created_at"`
			SystemTopicId uint      `json:"system_topic_id"` //数据库题目Id
			TopicId       string    `json:"topic_id"`        //题目自定义Id
			ProjectId     string    `json:"project_id"`      //项目自定义Id
			UserId        string    `json:"user_id"`         //用户自定义Id
			Tp            int       `json:"tp"`              //记录类型 0 放弃题目 1 领取题目 2 提交答案
			GiveUpReason  string    `json:"give_up_reason"`  //放弃原因
		}
		var userRecordServe services.CommonService[TopicUserRecord]
		filed := fmt.Sprintf("tas_topic_user_record.*,u.real_name as real_name")
		userRecordServe.SelectField = &filed
		userRecordServe.Query = map[string]interface{}{"tas_topic_user_record.user_id": userIds, "system_topic_id": topicId}
		userRecordServe.LeftJoin = append(userRecordServe.LeftJoin, fmt.Sprintf("left join tas_system_user as u on u.user_id=tas_topic_user_record.user_id"))
		userRecordServe.PageSize = -1
		res, _ := userRecordServe.SelectList()
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"detail": systemTopic, "user_list": res}})
		return
	}
}

// @Summary 批量处理回归题库
// @Description 批量处理回归题库
// @Tags 项目
// @Accept  multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量处理回归题库参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/regression_question_bank/{project_id} [post]
func RegressionQuestionBankHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		fmt.Println(err)
	}
	xlFile, err := xlsx.OpenBinary(fileByte)
	if err != nil {
		fmt.Printf("open failed: %s\n", err)
	}
	titles := []string{"题目ID", "生效时间", "截止时间"}
	var topicServe services.TopicService
	var res ImportsResponse
	var cnm = runtime.NumCPU() - 1
	runtime.GOMAXPROCS(cnm)
	//wg := sync.WaitGroup{}
	for _, sheet := range xlFile.Sheets {
		for i, row := range sheet.Rows {
			var errListLength = len(res.ErrList)
			//判断excel格式对不对
			if i == 0 {
				for j, title := range titles {
					if row.Cells[j].String() != title {
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
						return
					}
				}
			}
			//从第三行开始
			if i >= 2 {
				//wg.Add(1)
				res.TotalRows += 1
				var rowsList []string
				var row_data string
				for j, cell := range row.Cells {
					text := strings.TrimSpace(cell.String())
					row_data += text
					if text == "" && j < len(titles) {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Cell:   j + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[j]),
						})
					}
					rowsList = append(rowsList, text)
				}
				if strings.TrimSpace(row_data) == "" {
					res.TotalRows -= 1
					break
				}
				if len(rowsList) < len(titles) {
					for k := len(rowsList); k < len(titles); k++ {
						res.ErrList = append(res.ErrList, code.ImportError{
							Number: i + 1,
							Cell:   k + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[k]),
						})
					}
					res.FailRows += 1
					continue
				}
				var TopicId = rowsList[0]
				if rowsList[0] != "" {
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[0]),
						})
					}
				}
				var topicDao dao.Common[dao.SystemTopic]
				topicDao.Query = map[string]interface{}{"topic_id": TopicId, "project_id": projectId}
				topic, err := topicDao.First(topicDao.Query)
				if err != nil {
					switch err {
					case gorm.ErrRecordNotFound:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: "该条数据不存在"})
					default:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: err.Error()})
					}
				}
				//生效时间
				var EffectiveTime time.Time
				if rowsList[1] != "" {
					EffectiveTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[1], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1]),
						})
					}
				}
				//截止时间
				var EndDateTime time.Time
				if rowsList[2] != "" {
					EndDateTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[2], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[2]),
						})
					}
				}
				if len(res.ErrList) > errListLength {
					if len(res.ErrList)-errListLength >= len(titles) {
						break
					} else {
						res.FailRows += 1
						continue
					}
				}
				if err := topicServe.BatchRegressionQuestionBank(topic.Id, EffectiveTime, EndDateTime); err != nil {
					switch mysqlhandler.MysqlErrCode(err) {
					case mysqlhandler.ErrDuplicateEntryCode:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: "该条数据已经存在"})
					default:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: err.Error()})
					}
					res.FailRows += 1
				}
			}
		}
		//wg.Wait()
	}
	redis.RedisGClient.SetNX("BatchRegressionQuestionBank", "value", time.Duration(1)*time.Second)
	res.SuccessRows = res.TotalRows - res.FailRows
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
	return
}

// @Summary 批量处理返修
// @Description 批量处理返修
// @Tags 项目
// @Accept  multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量处理返修参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/repair/{project_id} [post]
func RepairTopicHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		fmt.Println(err)
	}
	xlFile, err := xlsx.OpenBinary(fileByte)
	if err != nil {
		fmt.Printf("open failed: %s\n", err)
	}
	titles := []string{"题目ID", "发题时间", "截止时间"}
	var topicServe services.TopicService
	var res ImportsResponse
	/*var cnm = runtime.NumCPU() - 1
	runtime.GOMAXPROCS(cnm)
	wg := sync.WaitGroup{}*/
	for _, sheet := range xlFile.Sheets {
		if len(sheet.Rows) >= 2 {
			res.TotalRows += len(sheet.Rows) - 2 //去掉表头和示例行
		} else {
			res.TotalRows += len(sheet.Rows)
		}

		for i, row := range sheet.Rows {
			var errListLength = len(res.ErrList)
			//判断excel格式对不对
			if i == 0 {
				for j, title := range titles {
					if row.Cells[j].String() != title {
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
						return
					}
				}
			}

			//从第三行开始
			if i >= 2 {
				var rowsList []string
				var rowData string
				for j, cell := range row.Cells {
					text := strings.TrimSpace(cell.String())
					rowData += text
					if text == "" && j < len(titles) {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Cell:   j + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[j]),
						})
					}
					rowsList = append(rowsList, text)
				}
				if strings.TrimSpace(rowData) == "" {
					res.TotalRows -= 1
					break
				}
				if len(rowsList) < len(titles) {
					for k := len(rowsList); k < len(titles); k++ {
						res.ErrList = append(res.ErrList, code.ImportError{
							Number: i + 1,
							Cell:   k + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[k]),
						})
					}
					res.FailRows += 1
					continue
				}
				var TopicId = rowsList[0]
				var topicDao dao.Common[dao.SystemTopic]
				topicDao.Query = map[string]interface{}{"topic_id": TopicId, "project_id": projectId}
				topic, err := topicDao.First(topicDao.Query)
				if err != nil {
					switch err {
					case gorm.ErrRecordNotFound:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行，该条数据不存在", i+1)})
					default:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: err.Error()})
					}
				}
				var EffectiveTime time.Time
				var EndTime time.Time
				//发题时间
				if rowsList[1] != "" {

					EffectiveTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[1], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1])})
					}
				}

				//截止时间
				if rowsList[2] != "" {

					EndTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[2], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[2])})
					}
				}
				if len(res.ErrList) > errListLength {
					if len(res.ErrList)-errListLength >= len(titles) {
						break
					} else {
						res.FailRows += 1
						continue
					}
				}
				//wg.Add(1)
				var ch = make(chan error)
				go topicServe.BatchTopicRepair(ch, topic.Id, EffectiveTime, EndTime)
				errs := <-ch
				defer close(ch)
				if errs != nil {
					switch mysqlhandler.MysqlErrCode(errs) {
					case mysqlhandler.ErrDuplicateEntryCode:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: "该条数据已经存在"})
					default:
						if gorm.ErrRecordNotFound == errs {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sheet.Name,
								Number: i + 1,
								Reason: fmt.Sprintf("题目%s,该题不存在,又或者是该题没有完成！", rowsList[0])})
						} else {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sheet.Name,
								Number: i + 1,
								Reason: errs.Error()})
						}
					}
					res.FailRows += 1
				}
			}
		}
		//wg.Wait()
	}
	redis.RedisGClient.SetNX("TopicRepair", "value", time.Duration(1)*time.Second)
	res.SuccessRows = res.TotalRows - res.FailRows
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
	return
}

// @Summary 批量处理指派
// @Description 批量处理指派
// @Tags 项目
// @Accept multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量处理指派参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/assign_user/{project_id} [post]
func TopicAssignUserHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		fmt.Println(err)
	}
	xlFile, err := xlsx.OpenBinary(fileByte)
	if err != nil {
		fmt.Printf("open failed: %s\n", err)
	}
	titles := []string{"题目ID", "发题日期", "截止时间", "指派用户ID"}
	var topicServe services.TopicService
	var res ImportsResponse
	var cnm = runtime.NumCPU() - 1
	runtime.GOMAXPROCS(cnm)
	wg := sync.WaitGroup{}
	for _, sheet := range xlFile.Sheets {
		for i, row := range sheet.Rows {
			var errListLength = len(res.ErrList)
			//判断excel格式对不对
			if i == 0 {
				for j, title := range titles {
					if row.Cells[j].String() != title {
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
						return
					}
				}
			}
			//从第三行开始
			if i >= 2 {
				res.TotalRows += 1
				var rowsList []string
				var row_data string
				for j, cell := range row.Cells {
					text := strings.TrimSpace(cell.String())
					row_data += text
					if text == "" && j < len(titles) {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Cell:   j + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[j]),
						})
					}
					rowsList = append(rowsList, text)
				}
				if strings.TrimSpace(row_data) == "" {
					res.TotalRows -= 1
					break
				}

				if len(rowsList) < len(titles) {
					for k := len(rowsList); k < len(titles); k++ {
						res.ErrList = append(res.ErrList, code.ImportError{
							Number: i + 1,
							Cell:   k + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[k]),
						})
					}
					res.FailRows += 1
					continue
				}
				//发题日期
				var EffectiveTime time.Time
				if rowsList[1] != "" {

					EffectiveTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[1], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1])})
					}
				}
				//截止时间
				var EndDateTime time.Time
				if rowsList[2] != "" {

					EndDateTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[2], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[2])})
					}
				}

				if len(res.ErrList) > errListLength {
					res.FailRows += 1
					continue
				}
				wg.Add(1)
				var ch = make(chan error)
				go topicServe.BatchAssignUser(ch, rowsList[0], projectId, rowsList[3], EffectiveTime, EndDateTime, &wg)
				errs, _ := <-ch
				defer close(ch)
				if errs != nil {
					switch mysqlhandler.MysqlErrCode(errs) {
					case mysqlhandler.ErrDuplicateEntryCode:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: "该条数据已经存在"})
					default:
						if gorm.ErrRecordNotFound == errs {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sheet.Name,
								Number: i + 1,
								Reason: fmt.Sprintf("题目%s,该题不存在,又或者是该题已经被作废！", rowsList[0])})
						} else {
							res.ErrList = append(res.ErrList, code.ImportError{
								Sheet:  sheet.Name,
								Number: i + 1,
								Reason: errs.Error()})
						}
					}
					res.FailRows += 1
				}
			}
		}
		wg.Wait()
	}
	redis.RedisGClient.SetNX("TopicAssignUser", "value", time.Duration(1)*time.Second)
	res.SuccessRows = res.TotalRows - res.FailRows
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
	return
}

// @Summary 批量作废
// @Description 批量作废
// @Tags 项目
// @Accept  multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "批量作废参数"
// @Param project_id path string true "项目Id"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/excel/invalid/{project_id} [post]
func InvalidTopicHandler(ctx iris.Context) {
	projectId := ctx.Params().Get("project_id")
	_, handle, err := ctx.FormFile("file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, _ := handle.Open()
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		fmt.Println(err)
	}
	xlFile, err := xlsx.OpenBinary(fileByte)
	if err != nil {
		fmt.Printf("open failed: %s\n", err)
	}
	titles := []string{"题目ID", "生效时间"}
	var topicServe services.TopicService
	var res ImportsResponse
	var cnm = runtime.NumCPU() - 1
	runtime.GOMAXPROCS(cnm)
	wg := sync.WaitGroup{}

	for _, sheet := range xlFile.Sheets {
		for i, row := range sheet.Rows {
			var errListLength = len(res.ErrList)
			//判断excel格式对不对
			if i == 0 {
				for j, title := range titles {
					if row.Cells[j].String() != title {
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: fmt.Sprintf("文件表头格式不对,%s", row.Cells[j].String())})
						return
					}
				}
			}
			//从第三行开始
			if i >= 2 {
				res.TotalRows += 1
				var rowsList []string
				var row_data string
				for j, cell := range row.Cells {
					text := strings.TrimSpace(cell.String())
					row_data += text
					if text == "" && j < len(titles) {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Cell:   j + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[j]),
						})
					}
					rowsList = append(rowsList, text)
				}
				if strings.TrimSpace(row_data) == "" {
					res.TotalRows -= 1
					break
				}
				if len(rowsList) < len(titles) {
					for k := len(rowsList); k < len(titles); k++ {
						res.ErrList = append(res.ErrList, code.ImportError{
							Number: i + 1,
							Cell:   k + 1,
							Reason: fmt.Sprintf("第%d行字段%s的值不能为空", i+1, titles[k]),
						})
					}
					res.FailRows += 1
					continue
				}
				var TopicId = rowsList[0]
				if rowsList[0] != "" {
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[0]),
						})
					}
				}
				var topicDao dao.Common[dao.SystemTopic]
				topicDao.Query = map[string]interface{}{"topic_id": TopicId, "project_id": projectId}
				topic, err := topicDao.First(topicDao.Query)
				if err != nil {
					switch err {
					case gorm.ErrRecordNotFound:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: "该条数据不存在"})
					default:
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: err.Error()})
					}
				}
				var EffectiveTime time.Time
				if rowsList[1] != "" {

					EffectiveTime, err = time.ParseInLocation(timehandler.FormatLayoutTime, rowsList[1], time.Local)
					if err != nil {
						res.ErrList = append(res.ErrList, code.ImportError{Sheet: sheet.Name, Number: i + 1, Reason: fmt.Sprintf("第%d行字段%s的时间格式错误", i+1, titles[1])})
					}
				}
				if len(res.ErrList) > errListLength {
					res.FailRows += 1
					continue
				}
				wg.Add(1)
				ch := make(chan error)
				go topicServe.BatchInvalidTopic(ch, topic, EffectiveTime, &wg)
				errs, _ := <-ch
				defer close(ch)
				if errs != nil {
					switch mysqlhandler.MysqlErrCode(errs) {
					case mysqlhandler.ErrDuplicateEntryCode:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: "该条数据已经存在"})
					default:
						res.ErrList = append(res.ErrList, code.ImportError{
							Sheet:  sheet.Name,
							Number: i + 1,
							Reason: errs.Error()})
					}
					res.FailRows += 1
				}
			}
		}
		wg.Wait()
	}
	redis.RedisGClient.SetNX("InvalidTopic", "value", time.Duration(1)*time.Second)
	res.SuccessRows = res.TotalRows - res.FailRows
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
	return
}

type BatchClearTopicUploadDataRequest struct {
	TopicIds  []string `json:"topic_ids"`
	ProjectId string   `json:"project_id"`
}

// @Summary 批量清空当前题目上传的答案
// @Description 批量清空当前题目上传的答案
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body BatchClearTopicUploadDataRequest true "批量清空当前题目上传的答案参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/batch_clear_upload_data [post]
func BatchClearUploadDataHandler(ctx iris.Context) {
	var RequestParams BatchClearTopicUploadDataRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	clientOss := oss.BucketClient{}
	var topicDao dao.Common[dao.SystemTopic]
	if topicList, err := topicDao.FindAll(map[string]interface{}{"project_id": RequestParams.ProjectId}); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		for _, topic := range topicList {
			clientOss.BatchRemoveFiles(fmt.Sprintf("%s/%s/", RequestParams.ProjectId, topic.TopicId))
		}
	}
	/*for _, id := range RequestParams.TopicIds {
		clientOss.BatchRemoveFiles(fmt.Sprintf("%s/%s/", RequestParams.ProjectId, id))
	}*/
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
	return
}

type BatchRemoveTopicRequest struct {
	Ids           []uint   `json:"ids"`
	ProjectId     string   `json:"project_id" validate:"required"`
	Title         string   `json:"title"`          //题目名称
	TopicId       string   `json:"topic_id"`       //题目ID
	Status        int      `json:"status"`         //状态 0 未生效 1已完成 2 已领取 3指派中 4返修中 5 闲置中 6 已作废
	EffectiveTime []string `json:"effective_time"` //题目生效时间
	EndDateTime   []string `json:"end_date_time"`  // 截止时间
	FinishTime    []string `json:"finish_time"`    //完成时间
	TeamNumber    string   `json:"team_number"`    //团队编号
	NickName      string   `json:"nick_name"`      //用户昵称
	RealName      string   `json:"real_name"`      // 姓名
	UserId        string   `json:"user_id"`        //用户Id
	AnswerStatus  string   `json:"answer_status"`  //答主题目状态
	OneStatus     string   `json:"one_status"`     //一审题目状态
}

// @Summary 批量删除当前题目
// @Description 批量删除当前题目
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body BatchRemoveTopicRequest true "批量删除当前题目参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/batch_del [post]
func BatchRemoveTopicHandler(ctx iris.Context) {
	var RequestParams BatchRemoveTopicRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	var topicServe services.TopicService
	topicIds := RequestParams.Ids
	if len(topicIds) == 0 {
		/*type SystemTopic struct {
			dao.SystemTopic
			TeamNumber   string `json:"team_number"`                //团队编号
			UserId       string `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName     string `json:"real_name"`                  // 姓名
			Phone        string `json:"phone"`                      //手机号
			NickName     string `json:"nick_name"`                  //用户昵称
			Email        string `json:"email"`                      //邮箱
			AnswerStatus string `json:"answer_status"`              //答主题目状态
			OneStatus    string `json:"one_status"`                 //一审题目状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		if claims.Type == 2 {
			for _, team := range admin.TeamPermissions {
				team_numbers = append(team_numbers, team)
			}
		}

		field := fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email")
		topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//如果是一审项目则需要查答主题目状态
			if project.EnumType == ENUM_TYPE_ONE {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//如果是二审项目则需要查一审题目状态跟答主题目状态
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,d.`status` one_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' and c.`status` = 1 ", project.AuditProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if utils.StringIsNotEmpty(RequestParams.OneStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("d.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and d.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else {
				if RequestParams.Status != -1 {
					//查询答主已完成题目排除返修中的
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and (tas_system_topic.reject_time is null or tas_system_topic.reject_time < now())", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				topicIds = append(topicIds, topic.Id)
			}
		}*/

		type SystemTopic struct {
			dao.SystemTopic
			TeamNumber     string    `json:"team_number"`                //团队编号
			UserId         string    `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName       string    `json:"real_name"`                  // 姓名
			Phone          string    `json:"phone"`                      //手机号
			NickName       string    `json:"nick_name"`                  //用户昵称
			Email          string    `json:"email"`                      //邮箱
			AnswerStatus   string    `json:"answer_status"`              //答主题目状态
			RejectTime     time.Time `json:"reject_time"`                //驳回时间
			OneStatus      string    `json:"one_status"`                 //一审题目状态
			OneAuditStatus string    `json:"one_audit_status"`           //一审审核状态
			TwoStatus      string    `json:"two_status"`                 //二审题目状态
			TwoAuditStatus string    `json:"two_audit_status"`           //二审审核状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		//if claims.Type == 2 {
		for _, team := range admin.TeamPermissions {
			team_numbers = append(team_numbers, team)
		}
		//}

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		field := ""
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//一审项目
			if project.EnumType == ENUM_TYPE_ONE {
				//如果有二审
				if utils.StringIsNotEmpty(project.FinalProjectId) {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status,d.status two_status,d.audit_status two_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
				} else {
					//如果没有二审只查答主的
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				}
				if RequestParams.Status != -1 {
					//一审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status != 0", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//一审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//二审项目
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,d.`status` one_status,d.audit_status one_audit_status,tas_system_topic.`status` two_status,tas_system_topic.audit_status two_audit_status")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.AuditProjectId))
				if RequestParams.Status != -1 {
					//二审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status = 2", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//二审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else {
				//答主项目
				//如果有一审
				if utils.StringIsNotEmpty(project.AuditProjectId) {
					//如果有二审
					if utils.StringIsNotEmpty(project.AuditProjectId) {
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status,d.`status` two_status,d.audit_status two_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
					} else {
						//没有二审只有一审
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
					}
				} else {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				}
				if RequestParams.Status != -1 {
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.reject_time < now()", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field
		topicServe.PageSize = -1

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				topicIds = append(topicIds, topic.Id)
			}
		}

	}
	if err := topicServe.BatchRemoveAllTopic(RequestParams.ProjectId, topicIds); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.StatusText(iris.StatusOK)})
		return
	}
}

type BatchExportTopicAnswerRequest struct {
	TopicIds      []uint   `json:"topic_ids"`
	ProjectIds    []string `json:"project_ids"`
	Title         string   `json:"title"` //题目名称
	ProjectId     string   `json:"project_id"`
	TopicId       string   `json:"topic_id"`       //题目ID
	Status        int      `json:"status"`         //状态 0 未生效 1已完成 2 已领取 3指派中 4返修中 5 闲置中 6 已作废
	EffectiveTime []string `json:"effective_time"` //题目生效时间
	EndDateTime   []string `json:"end_date_time"`  // 截止时间
	FinishTime    []string `json:"finish_time"`    //完成时间
	TeamNumber    string   `json:"team_number"`    //团队编号
	NickName      string   `json:"nick_name"`      //用户昵称
	RealName      string   `json:"real_name"`      // 姓名
	UserId        string   `json:"user_id"`        //用户Id
	AnswerStatus  string   `json:"answer_status"`  //答主题目状态
	OneStatus     string   `json:"one_status"`     //一审题目状态
}

// @Summary 批量导出题目和答案
// @Description 批量导出题目的答案
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body BatchExportTopicAnswerRequest true "批量导出题目和答案参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/answer/excel/export [post]
func BatchExportTopicAnswerHandler(ctx iris.Context) {
	var RequestParams BatchExportTopicAnswerRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	if len(RequestParams.TopicIds) == 0 {
		type SystemTopic struct {
			dao.SystemTopic
			TeamNumber   string `json:"team_number"`                //团队编号
			UserId       string `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName     string `json:"real_name"`                  // 姓名
			Phone        string `json:"phone"`                      //手机号
			NickName     string `json:"nick_name"`                  //用户昵称
			Email        string `json:"email"`                      //邮箱
			AnswerStatus string `json:"answer_status"`              //答主题目状态
			OneStatus    string `json:"one_status"`                 //一审题目状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		//if claims.Type == 2 {
		for _, team := range admin.TeamPermissions {
			team_numbers = append(team_numbers, team)
		}
		//}

		field := fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email")
		topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//如果是一审项目则需要查答主题目状态
			if project.EnumType == ENUM_TYPE_ONE {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//如果是二审项目则需要查一审题目状态跟答主题目状态
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,d.`status` one_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' and c.`status` = 1 ", project.AuditProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if utils.StringIsNotEmpty(RequestParams.OneStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("d.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and d.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else {
				if RequestParams.Status != -1 {
					//查询答主已完成题目排除返修中的
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and (tas_system_topic.reject_time is null or tas_system_topic.reject_time < now())", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				RequestParams.TopicIds = append(RequestParams.TopicIds, topic.Id)
			}
		}
	}

	var topicAnswerServer services.TopicAnswerService
	ExportData, err := topicAnswerServer.ExportAnswer(RequestParams.TopicIds, RequestParams.ProjectIds)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	exportFile := excelize.NewFile()
	style, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#8ED3F5", "#8ED3F5"}, Shading: 1},
	})
	style1, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#F1B735", "#F1B735"}, Shading: 1},
	})
	//创建工作表行数
	var excel = make(map[string][]interface{}, 0)
	//比较表头的长度
	var excelHeader = make(map[string]int, 0)
	titles := []string{"项目ID", "发题日期", "题目序号", "题目ID", "题目名称", "本题开放回答的时间", "截止时间", "完成时间", "填写领取老师姓名", "放弃原因"}
	//删除默认工作表
	for _, datum := range ExportData {
		sheetsTitle := titles
		//处理表头
		colNameDefault := generateColName(10)
		var rowsData []interface{}
		rowsData = append(rowsData, datum.ProjectId)
		rowsData = append(rowsData, datum.PushTopicDate.Format(timehandler.FormatLayoutDate))
		rowsData = append(rowsData, datum.SN)
		rowsData = append(rowsData, datum.TopicId)
		rowsData = append(rowsData, datum.TopicTitle)
		rowsData = append(rowsData, datum.EffectiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.EndDateTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.ReceiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.RealName)
		rowsData = append(rowsData, datum.GiveUpReason)
		sheet := fmt.Sprintf("%s_%s", datum.ProjectId, datum.BatchId)
		excel[sheet] = append(excel[sheet], rowsData)
		exportFile.NewSheet(sheet)
		startName := generateColName(len(titles) + 1)

		//处理题目配置和答案
		var answerList []interface{}
		//类型 、选填 、标题、内容
		stringsDeduplicate := arrays.StringsDeduplicate(strings.Split(datum.Answers, "[@@]"))
		for i, a := range stringsDeduplicate {
			splitAnswer := strings.Split(a, "[#]")
			if len(splitAnswer) < 4 {
				continue
			}
			title := fmt.Sprintf("提交内容-%d：", i+1)
			if splitAnswer[0] == "1" {
				splitAnswer[3] = utils.UrlFileNameEncode(splitAnswer[3])
				currentColName := generateColName(len(titles) + len(answerList) + 1)
				exportFile.SetCellHyperLink(sheet, fmt.Sprintf("%s%d", currentColName, len(excel[sheet])+1), splitAnswer[3], "External")
				title += "文件上传"
			} else {
				title += "在线文本"
			}
			if splitAnswer[1] == "0" {
				title += "（必填）"
			} else {
				title += "（选填）"
			}
			title += "-" + splitAnswer[2]
			sheetsTitle = append(sheetsTitle, title)
			answerList = append(answerList, splitAnswer[3])

		}
		endName := generateColName(len(titles) + len(answerList))

		rowsData = append(rowsData, answerList...)
		if len(sheetsTitle)-len(rowsData) > 0 {
			var NullSlice = make([]interface{}, len(sheetsTitle)-len(rowsData))
			rowsData = append(rowsData, NullSlice...)
		}
		//计算备注的长度
		var noteList []interface{}
		for i, s := range strings.Split(datum.Note, "[@@]") {
			splitHeader := strings.Split(s, "[#]")
			sheetsTitle = append(sheetsTitle, fmt.Sprintf("备注%d", i+1))
			noteList = append(noteList, splitHeader[1])
		}
		rowsData = append(rowsData, noteList...)

		exportFile.SetCellStyle(sheet, "A1", colNameDefault+"1", style)
		exportFile.SetCellStyle(sheet, startName+"1", endName+"1", style1)
		//插入表头
		if _, ok := excelHeader[sheet]; ok {
			if excelHeader[sheet] < len(sheetsTitle) {
				exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
				excelHeader[sheet] = len(sheetsTitle)
			}
		} else {
			exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
			excelHeader[sheet] = len(sheetsTitle)
		}
		//插入内容
		exportFile.SetSheetRow(sheet, fmt.Sprintf("A+%d", len(excel[sheet])+1), &rowsData)
	}
	exportFile.DeleteSheet("Sheet1")
	unix := time.Now().UnixNano()
	tempFilename := fmt.Sprintf("./export/topic_answer_%d.xlsx", unix)
	if err := exportFile.SaveAs(tempFilename); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	defer exportFile.Close()
	//删除本地临时文件
	defer os.Remove(tempFilename)
	bucketClient := oss.BucketClient{}
	readFile, _ := ioutil.ReadFile(fmt.Sprintf("./export/topic_answer_%d.xlsx", unix))
	bucketClient.UpBytes(readFile, fmt.Sprintf("task-assign/answer/export/topic_answer_%d.xlsx", unix))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/task-assign/answer/export/topic_answer_%d.xlsx", utils.ServerConf.AliOssConf.CallBackHost, unix)})
	return
}

// @Summary 批量导出当前所有题目和答案
// @Description 批量导出当前所有题目和答案
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body TopicListRequest true "批量导出当前所有题目和答案参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/topic/answer/excel/export_all [post]
func BatchExportAllTopicAnswerHandler(ctx iris.Context) {
	var RequestParams TopicListRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	type SystemTopic struct {
		dao.SystemTopic
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var common dao.Common[dao.SystemAdmin]
	admin, _ := common.First(map[string]interface{}{"id": claims.Id})

	var topicServe services.CommonService[SystemTopic]
	topicServe.PageSize = -1
	topicServe.Query = map[string]interface{}{}

	//处理团队权限
	var team_numbers []string
	//if claims.Type == 2 {
	for _, team := range admin.TeamPermissions {
		team_numbers = append(team_numbers, team)
	}
	//}
	if RequestParams.Status != -1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
	}
	if len(team_numbers) > 0 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
	}
	if RequestParams.Title != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
	}
	if RequestParams.TopicId != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
	}
	if RequestParams.TeamNumber != "" {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
	}
	topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
	field := fmt.Sprintf("tas_system_topic.id,tas_system_user.user_id")
	topicServe.SelectField = &field
	topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
	if len(RequestParams.EffectiveTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
	}
	if len(RequestParams.EndDateTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
	}
	if len(RequestParams.FinishTime) > 1 {
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
	}
	topicServe.Order = "tas_system_topic.sn"
	res, _ := topicServe.SelectList1()
	var TopicIds []uint
	for _, topic := range res.Data {
		TopicIds = append(TopicIds, topic.Id)
	}
	var ExportData []services.ExportResponse
	idx := 0
	caps := 4000
	_db := mysql.GetDB()
	for idx < len(TopicIds) {
		endIdx := idx + caps
		if endIdx > len(TopicIds) {
			endIdx = len(TopicIds)
		}

		func(TopicIds []uint, db *gorm.DB) {
			//defer wg.Done()
			var topicAnswerServer services.TopicAnswerService
			exportData, _ := topicAnswerServer.ExportAnswerTx(TopicIds, []string{}, db)
			ExportData = append(ExportData, exportData...)
		}(TopicIds[idx:endIdx], _db)
		idx += caps
	}
	//wgs.Wait()
	exportFile := excelize.NewFile()
	style, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#8ED3F5", "#8ED3F5"}, Shading: 1},
	})
	style1, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#F1B735", "#F1B735"}, Shading: 1},
	})
	//创建工作表行数
	var excel = make(map[string][]interface{}, 0)
	//比较表头的长度
	var excelHeader = make(map[string]int, 0)
	titles := []string{"项目ID", "发题日期", "题目序号", "题目ID", "题目名称", "本题开放回答的时间", "截止时间", "完成时间", "填写领取老师姓名", "放弃原因"}
	//删除默认工作表
	wg := sync.WaitGroup{}

	for _, datum := range ExportData {
		sheetsTitle := titles
		//处理表头
		colNameDefault := generateColName(10)
		var rowsData []interface{}
		rowsData = append(rowsData, datum.ProjectId)
		rowsData = append(rowsData, datum.PushTopicDate.Format(timehandler.FormatLayoutDate))
		rowsData = append(rowsData, datum.SN)
		rowsData = append(rowsData, datum.TopicId)
		rowsData = append(rowsData, datum.TopicTitle)
		rowsData = append(rowsData, datum.EffectiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.EndDateTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.ReceiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.RealName)
		rowsData = append(rowsData, datum.GiveUpReason)
		sheet := fmt.Sprintf("%s_%s", datum.ProjectId, datum.BatchId)
		excel[sheet] = append(excel[sheet], rowsData)
		exportFile.NewSheet(sheet)
		startName := generateColName(len(titles) + 1)

		//处理题目配置和答案
		var answerList []interface{}
		//类型 、选填 、标题、内容

		stringsDeduplicate := arrays.StringsDeduplicate(strings.Split(datum.Answers, "[@@]"))
		for i, a := range stringsDeduplicate {
			splitAnswer := strings.Split(a, "[#]")
			if len(splitAnswer) < 4 {
				continue
			}
			title := fmt.Sprintf("提交内容-%d：", i+1)
			if splitAnswer[0] == "1" {
				splitAnswer[3] = utils.UrlFileNameEncode(splitAnswer[3])
				currentColName := generateColName(len(titles) + len(answerList) + 1)
				exportFile.SetCellHyperLink(sheet, fmt.Sprintf("%s%d", currentColName, len(excel[sheet])+1), splitAnswer[3], "External")
				title += "文件上传"
			} else {
				title += "在线文本"
			}
			if splitAnswer[1] == "0" {
				title += "（必填）"
			} else {
				title += "（选填）"
			}
			title += "-" + splitAnswer[2]
			sheetsTitle = append(sheetsTitle, title)
			answerList = append(answerList, splitAnswer[3])

		}
		endName := generateColName(len(titles) + len(answerList))

		rowsData = append(rowsData, answerList...)
		if len(sheetsTitle)-len(rowsData) > 0 {
			var NullSlice = make([]interface{}, len(sheetsTitle)-len(rowsData))
			rowsData = append(rowsData, NullSlice...)
		}
		//计算备注的长度
		var noteList []interface{}
		for i, s := range strings.Split(datum.Note, "[@@]") {
			splitHeader := strings.Split(s, "[#]")
			sheetsTitle = append(sheetsTitle, fmt.Sprintf("备注%d", i+1))
			noteList = append(noteList, splitHeader[1])
		}
		rowsData = append(rowsData, noteList...)

		exportFile.SetCellStyle(sheet, "A1", colNameDefault+"1", style)
		exportFile.SetCellStyle(sheet, startName+"1", endName+"1", style1)
		//插入表头
		if _, ok := excelHeader[sheet]; ok {
			if excelHeader[sheet] < len(sheetsTitle) {
				exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
				excelHeader[sheet] = len(sheetsTitle)
			}
		} else {
			exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
			excelHeader[sheet] = len(sheetsTitle)
		}
		//插入内容
		wg.Add(1)
		go func(exportFile *excelize.File, sheet string, axis string, rowsData []interface{}, wg *sync.WaitGroup) {
			exportFile.SetSheetRow(sheet, axis, &rowsData)
			defer wg.Done()
		}(exportFile, sheet, fmt.Sprintf("A+%d", len(excel[sheet])+1), rowsData, &wg)

	}
	wg.Wait()
	exportFile.DeleteSheet("Sheet1")
	unix := time.Now().UnixNano()
	tempFilename := fmt.Sprintf("./export/topic_answer_%d.xlsx", unix)
	if err := exportFile.SaveAs(tempFilename); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	defer exportFile.Close()
	//删除本地临时文件
	defer os.Remove(tempFilename)
	bucketClient := oss.BucketClient{}
	readFile, _ := ioutil.ReadFile(fmt.Sprintf("./export/topic_answer_%d.xlsx", unix))
	bucketClient.UpBytes(readFile, fmt.Sprintf("task-assign/answer/export/topic_answer_%d.xlsx", unix))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/task-assign/answer/export/topic_answer_%d.xlsx", utils.ServerConf.AliOssConf.CallBackHost, unix)})
	return
}

func generateColName(cellLength int) string {
	var colName string
	dividend := cellLength
	var modulo int
	for dividend > 0 {
		modulo = (dividend - 1) % 26
		// Convert int to string
		colName = string(modulo+65) + colName
		dividend = (int)((dividend - modulo) / 26)
	}
	return colName
}

// @Summary 批量导出当前所有题目和答案
// @Description 批量导出当前所有题目和答案
// @Tags 项目
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param param body SearchProjectListRequest true "批量导出当前所有题目和答案参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /admin/project/answer/excel/export_all [post]
func BatchExportProjectAllTopicAnswerHandler(ctx iris.Context) {
	var RequestParams SearchProjectListRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	var service services.CommonService[dao.SystemProject]
	service.Query = map[string]interface{}{}

	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var common dao.Common[dao.SystemAdmin]
	admin, _ := common.First(map[string]interface{}{"id": claims.Id})
	//if claims.Type == 2 {
	var pIds []string
	//处理项目权限
	for _, permission := range admin.ProjectPermissions {
		pIds = append(pIds, permission)
	}
	service.Query["project_id"] = pIds
	//处理团队权限
	for _, team := range admin.TeamPermissions {
		fmt.Println("team", team)
	}

	//}
	if RequestParams.Status != -1 {
		service.Query["status"] = RequestParams.Status
	}
	if RequestParams.ProjectId != "" {
		service.WhereStr = append(service.WhereStr, fmt.Sprintf("project_id LIKE '%%%v%%'", RequestParams.ProjectId))
	}
	if len(RequestParams.OnlineDateTime) > 0 {
		service.WhereStr = append(service.WhereStr, fmt.Sprintf("online_date_time BETWEEN '%s' AND '%s'", RequestParams.OnlineDateTime[0], RequestParams.OnlineDateTime[1]))
	}
	if len(RequestParams.OfflineDateTime) > 0 {
		service.WhereStr = append(service.WhereStr, fmt.Sprintf("offline_date_time BETWEEN '%s' AND '%s'", RequestParams.OfflineDateTime[0], RequestParams.OfflineDateTime[1]))
	}
	if RequestParams.SearchText != "" {
		service.WhereStr = append(service.WhereStr, fmt.Sprintf("title LIKE '%%%v%%'", RequestParams.SearchText))
	}

	findAll, _ := service.FindAll()
	var ProjectIds []string
	for _, project := range findAll {
		ProjectIds = append(ProjectIds, project.ProjectId)
	}
	var topicAnswerServer services.TopicAnswerService
	ExportData, err := topicAnswerServer.ExportAnswer([]uint{}, ProjectIds)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	exportFile := excelize.NewFile()
	style, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#8ED3F5", "#8ED3F5"}, Shading: 1},
	})
	style1, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#F1B735", "#F1B735"}, Shading: 1},
	})
	//创建工作表行数
	var excel = make(map[string][]interface{}, 0)
	//比较表头的长度
	var excelHeader = make(map[string]int, 0)
	titles := []string{"项目ID", "发题日期", "题目序号", "题目ID", "题目名称", "本题开放回答的时间", "截止时间", "完成时间", "填写领取老师姓名", "放弃原因"}
	//删除默认工作表
	for _, datum := range ExportData {
		sheetsTitle := titles
		//处理表头
		colNameDefault := generateColName(10)
		var rowsData []interface{}
		rowsData = append(rowsData, datum.ProjectId)
		rowsData = append(rowsData, datum.PushTopicDate.Format(timehandler.FormatLayoutDate))
		rowsData = append(rowsData, datum.SN)
		rowsData = append(rowsData, datum.TopicId)
		rowsData = append(rowsData, datum.TopicTitle)
		rowsData = append(rowsData, datum.EffectiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.EndDateTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.ReceiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.RealName)
		rowsData = append(rowsData, datum.GiveUpReason)
		sheet := fmt.Sprintf("%s_%s", datum.ProjectId, datum.BatchId)
		excel[sheet] = append(excel[sheet], rowsData)
		exportFile.NewSheet(sheet)
		startName := generateColName(len(titles) + 1)

		//处理题目配置和答案
		var answerList []interface{}
		//类型 、选填 、标题、内容
		stringsDeduplicate := arrays.StringsDeduplicate(strings.Split(datum.Answers, "[@@]"))
		for i, a := range stringsDeduplicate {
			splitAnswer := strings.Split(a, "[#]")
			if len(splitAnswer) < 4 {
				continue
			}
			title := fmt.Sprintf("提交内容-%d：", i+1)
			if splitAnswer[0] == "1" {
				splitAnswer[3] = utils.UrlFileNameEncode(splitAnswer[3])
				currentColName := generateColName(len(titles) + len(answerList) + 1)
				exportFile.SetCellHyperLink(sheet, fmt.Sprintf("%s%d", currentColName, len(excel[sheet])+1), splitAnswer[3], "External")
				title += "文件上传"
			} else {
				title += "在线文本"
			}
			if splitAnswer[1] == "0" {
				title += "（必填）"
			} else {
				title += "（选填）"
			}
			title += "-" + splitAnswer[2]
			sheetsTitle = append(sheetsTitle, title)
			answerList = append(answerList, splitAnswer[3])

		}
		endName := generateColName(len(titles) + len(answerList))

		rowsData = append(rowsData, answerList...)
		if len(sheetsTitle)-len(rowsData) > 0 {
			var NullSlice = make([]interface{}, len(sheetsTitle)-len(rowsData))
			rowsData = append(rowsData, NullSlice...)
		}
		//计算备注的长度
		var noteList []interface{}
		for i, s := range strings.Split(datum.Note, "[@@]") {
			splitHeader := strings.Split(s, "[#]")
			sheetsTitle = append(sheetsTitle, fmt.Sprintf("备注%d", i+1))
			noteList = append(noteList, splitHeader[1])
		}
		rowsData = append(rowsData, noteList...)

		exportFile.SetCellStyle(sheet, "A1", colNameDefault+"1", style)
		exportFile.SetCellStyle(sheet, startName+"1", endName+"1", style1)
		//插入表头
		if _, ok := excelHeader[sheet]; ok {
			if excelHeader[sheet] < len(sheetsTitle) {
				exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
				excelHeader[sheet] = len(sheetsTitle)
			}
		} else {
			exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
			excelHeader[sheet] = len(sheetsTitle)
		}
		//插入内容
		exportFile.SetSheetRow(sheet, fmt.Sprintf("A+%d", len(excel[sheet])+1), &rowsData)
	}
	exportFile.DeleteSheet("Sheet1")
	unix := time.Now().UnixNano()
	tempFilename := fmt.Sprintf("./export/topic_answer_%d.xlsx", unix)
	if err := exportFile.SaveAs(tempFilename); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	defer exportFile.Close()
	//删除本地临时文件
	defer os.Remove(tempFilename)
	bucketClient := oss.BucketClient{}
	readFile, _ := ioutil.ReadFile(fmt.Sprintf("./export/topic_answer_%d.xlsx", unix))
	bucketClient.UpBytes(readFile, fmt.Sprintf("task-assign/answer/export/topic_answer_%d.xlsx", unix))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/task-assign/answer/export/topic_answer_%d.xlsx", utils.ServerConf.AliOssConf.CallBackHost, unix)})
	return
}

type UpdateUserRestrictionRequest struct {
	OpenUserRestriction  string `json:"open_user_restriction"`  //开启用户权限
	CloseUserRestriction string `json:"close_user_restriction"` //关闭用户权限
	UserId               string `json:"user_id"`                //用户ID
}

func UpdateUserRestrictionHandler(ctx iris.Context) {
	var RequestParams UpdateUserRestrictionRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var userServe dao.Common[dao.SystemUser]
	if user, err := userServe.First(map[string]interface{}{"user_id": RequestParams.UserId}); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		projectMapOpen := make(map[string]string)
		var systemUserRestrictions []*dao.SystemUserRestriction
		var projectServe dao.Common[dao.SystemProject]
		var userRestrictionServe dao.Common[dao.SystemUserRestriction]
		if utils.StringIsNotEmpty(RequestParams.OpenUserRestriction) {
			userOpens := strings.Split(RequestParams.OpenUserRestriction, "，")
			//判断开启用户权限的项目存不存在,判断该用户是否存在该权限
			for _, open := range userOpens {
				if count, err := projectServe.Count(map[string]interface{}{"project_id": open}); err != nil {
					ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
					return
				} else {
					if count == 0 {
						msg := fmt.Sprintf("需要开启权限的项目:(%v)不存在", open)
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: msg})
						return
					}
				}

				if count, err := userRestrictionServe.Count(map[string]interface{}{"system_user_id": user.Id, "project_id": open}); err != nil {
					ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
					return
				} else {
					if count > 0 {
						msg := fmt.Sprintf("该用户已存在项目:(%v)的权限,无需重复开启", open)
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: msg})
						return
					}
				}

				if project, err := projectServe.First(map[string]interface{}{"project_id": open}); err != nil {
					ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
					return
				} else {
					var systemUserRestriction dao.SystemUserRestriction
					systemUserRestriction.ProjectId = open
					systemUserRestriction.SystemUserId = user.Id
					systemUserRestriction.LowerLimit = 1
					systemUserRestriction.LowerLimit = project.LowerLimit
					systemUserRestriction.Limit = project.Limit
					systemUserRestriction.DayLimit = uint(project.DayLimit)
					systemUserRestriction.DayGiveUpLimit = uint(project.DayGiveUpLimit)
					systemUserRestrictions = append(systemUserRestrictions, &systemUserRestriction)

					key := open
					projectMapOpen[key] = "- " + project.Title + " 项目权限已开启"
				}
			}
			//开启用户项目权限
			if len(systemUserRestrictions) > 0 {
				userRestrictionServe.CreateT(systemUserRestrictions)
				for key, value := range projectMapOpen {
					redis.RedisGClient.SAdd(fmt.Sprintf("UnreadMessages_%d", user.Id), key+value)
				}
			}
		}

		//关闭用户权限
		if utils.StringIsNotEmpty(RequestParams.CloseUserRestriction) {
			userCloses := strings.Split(RequestParams.CloseUserRestriction, "，")
			for _, close := range userCloses {
				if count, err := projectServe.Count(map[string]interface{}{"project_id": close}); err != nil {
					ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
					return
				} else {
					if count == 0 {
						msg := fmt.Sprintf("需要关闭权限的项目:(%v)不存在", close)
						ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: msg})
						return
					}
				}
			}
			for _, userClose := range userCloses {
				userRestrictionServe.RemoveUnscopedPreload(map[string]interface{}{"system_user_id": user.Id, "project_id": userClose})

				if project, err := projectServe.First(map[string]interface{}{"project_id": userClose}); err == nil {
					msg := project.ProjectId + "- " + project.Title + " 项目权限已关闭"
					redis.RedisGClient.SAdd(fmt.Sprintf("UnreadMessages_%d", user.Id), msg)
				}
			}
		}

		ctx.JSON(utils.ResponseOK())
		return
	}
}

func BatchExportTopicAnswerNewHandler(ctx iris.Context) {
	var RequestParams BatchExportTopicAnswerRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	if len(RequestParams.TopicIds) == 0 {
		/*type SystemTopic struct {
			dao.SystemTopic
			TeamNumber   string `json:"team_number"`                //团队编号
			UserId       string `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName     string `json:"real_name"`                  // 姓名
			Phone        string `json:"phone"`                      //手机号
			NickName     string `json:"nick_name"`                  //用户昵称
			Email        string `json:"email"`                      //邮箱
			AnswerStatus string `json:"answer_status"`              //答主题目状态
			OneStatus    string `json:"one_status"`                 //一审题目状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		if claims.Type == 2 {
			for _, team := range admin.TeamPermissions {
				team_numbers = append(team_numbers, team)
			}
		}

		field := fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email")
		topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//如果是一审项目则需要查答主题目状态
			if project.EnumType == ENUM_TYPE_ONE {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//如果是二审项目则需要查一审题目状态跟答主题目状态
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,d.`status` one_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' and c.`status` = 1 ", project.AuditProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if utils.StringIsNotEmpty(RequestParams.OneStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("d.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and d.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else {
				if RequestParams.Status != -1 {
					//查询答主已完成题目排除返修中的
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and (tas_system_topic.reject_time is null or tas_system_topic.reject_time < now())", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				RequestParams.TopicIds = append(RequestParams.TopicIds, topic.Id)
			}
		}*/

		type SystemTopic struct {
			dao.SystemTopic
			TeamNumber     string    `json:"team_number"`                //团队编号
			UserId         string    `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName       string    `json:"real_name"`                  // 姓名
			Phone          string    `json:"phone"`                      //手机号
			NickName       string    `json:"nick_name"`                  //用户昵称
			Email          string    `json:"email"`                      //邮箱
			AnswerStatus   string    `json:"answer_status"`              //答主题目状态
			RejectTime     time.Time `json:"reject_time"`                //驳回时间
			OneStatus      string    `json:"one_status"`                 //一审题目状态
			OneAuditStatus string    `json:"one_audit_status"`           //一审审核状态
			TwoStatus      string    `json:"two_status"`                 //二审题目状态
			TwoAuditStatus string    `json:"two_audit_status"`           //二审审核状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		//if claims.Type == 2 {
		for _, team := range admin.TeamPermissions {
			team_numbers = append(team_numbers, team)
		}
		//}

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		field := ""
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//一审项目
			if project.EnumType == ENUM_TYPE_ONE {
				//如果有二审
				if utils.StringIsNotEmpty(project.FinalProjectId) {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status,d.status two_status,d.audit_status two_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
				} else {
					//如果没有二审只查答主的
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				}
				if RequestParams.Status != -1 {
					//一审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status != 0", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//一审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//二审项目
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,d.`status` one_status,d.audit_status one_audit_status,tas_system_topic.`status` two_status,tas_system_topic.audit_status two_audit_status")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.AuditProjectId))
				if RequestParams.Status != -1 {
					//二审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status = 2", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//二审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else {
				//答主项目
				//如果有一审
				if utils.StringIsNotEmpty(project.AuditProjectId) {
					//如果有二审
					if utils.StringIsNotEmpty(project.AuditProjectId) {
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status,d.`status` two_status,d.audit_status two_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
					} else {
						//没有二审只有一审
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
					}
				} else {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				}
				if RequestParams.Status != -1 {
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.reject_time < now()", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field
		topicServe.PageSize = -1

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				RequestParams.TopicIds = append(RequestParams.TopicIds, topic.Id)
			}
		}
	}

	var topicAnswerServer services.TopicAnswerService
	ExportData, err := topicAnswerServer.ExportAnswerNew(RequestParams.TopicIds, RequestParams.ProjectIds)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var projectDao dao.Common[dao.SystemProject]
	project, err := projectDao.First(map[string]interface{}{"project_id": RequestParams.ProjectId})
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	exportFile := excelize.NewFile()
	style, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#8ED3F5", "#8ED3F5"}, Shading: 1},
	})
	style1, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#F1B735", "#F1B735"}, Shading: 1},
	})
	//创建工作表行数
	var excel = make(map[string][]interface{}, 0)
	//比较表头的长度
	var excelHeader = make(map[string]int, 0)
	titles := []string{"项目ID", "发题日期", "题目序号", "题目ID", "题目名称", "题目检索标签(如不填写，则默认搜可搜素题目名字)", "题目生效时间", "截止时间", "备注", "题目状态", "一审状态", "二审状态", "操作时间", "答主老师用户ID", "答主昵称", "答主姓名", "答主团队编号", "答主手机号", "答主邮箱", "放弃原因"}
	//删除默认工作表
	for _, datum := range ExportData {
		sheetsTitle := titles
		//处理表头
		colNameDefault := generateColName(20)
		var rowsData []interface{}
		rowsData = append(rowsData, datum.ProjectId)
		rowsData = append(rowsData, datum.PushTopicDate.Format(timehandler.FormatLayoutDate))
		rowsData = append(rowsData, datum.SN)
		rowsData = append(rowsData, datum.TopicId)
		rowsData = append(rowsData, datum.TopicTitle)
		rowsData = append(rowsData, datum.Labels)
		rowsData = append(rowsData, datum.EffectiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.EndDateTime.Format(timehandler.FormatLayoutTime))
		if note, err := topicAnswerServer.GetTopicNoteInfo(datum.SystemTopicId); err == nil {
			rowsData = append(rowsData, note)
		} else {
			rowsData = append(rowsData, "")
		}
		workProjectId := ""
		auditProjectId := ""
		finalProjectId := ""
		if project.EnumType == modelbase.WorkProj {
			workProjectId = project.ProjectId
			auditProjectId = project.AuditProjectId
			finalProjectId = project.FinalProjectId
		} else if project.EnumType == modelbase.AuditProj {
			workProjectId = project.WorkProjectId
			auditProjectId = project.ProjectId
			finalProjectId = project.FinalProjectId
		} else if project.EnumType == modelbase.FinalProj {
			workProjectId = project.WorkProjectId
			auditProjectId = project.AuditProjectId
			finalProjectId = project.ProjectId
		}
		if res, err := topicAnswerServer.GetTopicStatusInfo(datum.TopicId, workProjectId, auditProjectId, finalProjectId, project.EnumType); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			workStatus := ""
			if utils.StringIsNotEmpty(res.AnswerStatus) {
				if res.AnswerStatus == "0" {
					workStatus = "未生效"
				} else if res.AnswerStatus == "1" {
					if res.RejectTime.After(time.Now()) {
						workStatus = "返修中"
					} else {
						workStatus = "已完成"
					}
				} else if res.AnswerStatus == "2" {
					workStatus = "已领取"
				} else if res.AnswerStatus == "3" {
					workStatus = "指派中"
				} else if res.AnswerStatus == "4" {
					workStatus = "返修中"
				} else if res.AnswerStatus == "5" {
					workStatus = "闲置中"
				} else if res.AnswerStatus == "6" {
					workStatus = "已作废"
				} else if res.AnswerStatus == "7" {
					workStatus = "已失效"
				}
				rowsData = append(rowsData, workStatus)
			} else {
				rowsData = append(rowsData, "")
			}

			if utils.StringIsNotEmpty(res.OneStatus) {
				oneStatus := ""
				if res.OneStatus == "0" {
					oneStatus = "未生效"
				} else if res.OneStatus == "1" {
					if res.OneAuditStatus != "0" {
						oneStatus = "审核通过"
					} else {
						oneStatus = "审核拒绝"
					}
				} else if res.OneStatus == "2" {
					oneStatus = "已领取"
				} else if res.OneStatus == "3" {
					oneStatus = "指派中"
				} else if res.OneStatus == "4" {
					oneStatus = "返修中"
				} else if res.OneStatus == "5" {
					oneStatus = "闲置中"
				} else if res.OneStatus == "6" {
					oneStatus = "已作废"
				} else if res.OneStatus == "7" {
					oneStatus = "已失效"
				}
				rowsData = append(rowsData, oneStatus)
			} else {
				rowsData = append(rowsData, "")
			}

			if utils.StringIsNotEmpty(res.TwoStatus) {
				twoStatus := ""
				if res.TwoStatus == "0" {
					twoStatus = "未生效"
				} else if res.TwoStatus == "1" {
					if res.TwoAuditStatus == "2" {
						twoStatus = "审核通过"
					} else {
						twoStatus = "审核拒绝"
					}
				} else if res.TwoStatus == "2" {
					twoStatus = "已领取"
				} else if res.TwoStatus == "3" {
					twoStatus = "指派中"
				} else if res.TwoStatus == "4" {
					twoStatus = "返修中"
				} else if res.TwoStatus == "5" {
					twoStatus = "闲置中"
				} else if res.TwoStatus == "6" {
					twoStatus = "已作废"
				} else if res.TwoStatus == "7" {
					twoStatus = "已失效"
				}
				rowsData = append(rowsData, twoStatus)
			} else {
				rowsData = append(rowsData, "")
			}
		}
		/*topicStatus := ""
		if datum.Status == 0 {
			topicStatus = "未生效"
		} else if datum.Status == 1 {
			if datum.RejectTime.After(time.Now()) {
				topicStatus = "返修中"
			} else {
				topicStatus = "已完成"
			}
		} else if datum.Status == 2 {
			topicStatus = "已领取"
		} else if datum.Status == 3 {
			topicStatus = "指派中"
		} else if datum.Status == 4 {
			topicStatus = "返修中"
		} else if datum.Status == 5 {
			topicStatus = "闲置中"
		} else if datum.Status == 6 {
			topicStatus = "已作废"
		} else if datum.Status == 7 {
			topicStatus = "已失效"
		}
		rowsData = append(rowsData, topicStatus)*/
		//操作时间
		rowsData = append(rowsData, datum.UpdatedAt.Format(timehandler.FormatLayoutTime))
		//答主老师用户ID
		rowsData = append(rowsData, datum.UserId)
		rowsData = append(rowsData, datum.NickName)
		rowsData = append(rowsData, datum.RealName)
		rowsData = append(rowsData, datum.TeamNumber)
		rowsData = append(rowsData, datum.Phone)
		rowsData = append(rowsData, datum.Email)
		if reason, err := topicAnswerServer.GetGiveUpReason(datum.SystemTopicId); err == nil {
			rowsData = append(rowsData, reason)
		} else {
			rowsData = append(rowsData, "")
		}
		sheet := fmt.Sprintf("%s_%s", datum.ProjectId, datum.BatchId)
		excel[sheet] = append(excel[sheet], rowsData)
		exportFile.NewSheet(sheet)

		var answerList []interface{}
		if answerListQuery, err := topicAnswerServer.GetTopicAnswerInfo(datum.SystemTopicId); err == nil {
			if len(answerListQuery) > 0 {
				for i, a := range answerListQuery {
					sheetsTitle = append(sheetsTitle, fmt.Sprintf("提交内容-%v %v-%v", i+1, a.Title, a.Tooltip))
					if a.AnswerType == 0 || a.AnswerType == 1 {
						answerList = append(answerList, a.Content)
					} else {
						answerList = append(answerList, a.ContentUrl+" "+a.FileUrl)
					}
				}
			}
		}

		rowsData = append(rowsData, answerList...)
		startName := generateColName(len(titles) + 1)
		endName := generateColName(len(titles) + len(answerList))
		exportFile.SetCellStyle(sheet, "A1", colNameDefault+"1", style)
		exportFile.SetCellStyle(sheet, startName+"1", endName+"1", style1)
		//插入表头
		if _, ok := excelHeader[sheet]; ok {
			if excelHeader[sheet] < len(sheetsTitle) {
				exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
				excelHeader[sheet] = len(sheetsTitle)
			}
		} else {
			exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
			excelHeader[sheet] = len(sheetsTitle)
		}
		//插入内容
		exportFile.SetSheetRow(sheet, fmt.Sprintf("A+%d", len(excel[sheet])+1), &rowsData)
	}
	exportFile.DeleteSheet("Sheet1")
	unix := time.Now().UnixNano()
	tempFilename := fmt.Sprintf("./export/topic_answer_%d.xlsx", unix)
	if err := exportFile.SaveAs(tempFilename); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	defer exportFile.Close()
	//删除本地临时文件
	defer os.Remove(tempFilename)
	bucketClient := oss.BucketClient{}
	readFile, _ := ioutil.ReadFile(fmt.Sprintf("./export/topic_answer_%d.xlsx", unix))
	bucketClient.UpBytes(readFile, fmt.Sprintf("task-assign/answer/export/topic_answer_%d.xlsx", unix))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/task-assign/answer/export/topic_answer_%d.xlsx", utils.ServerConf.AliOssConf.CallBackHost, unix)})
	return
}

func BatchExportTopicAuditNewHandler(ctx iris.Context) {
	var RequestParams BatchExportTopicAnswerRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	if len(RequestParams.TopicIds) == 0 {
		/*type SystemTopic struct {
			dao.SystemTopic
			TeamNumber   string `json:"team_number"`                //团队编号
			UserId       string `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName     string `json:"real_name"`                  // 姓名
			Phone        string `json:"phone"`                      //手机号
			NickName     string `json:"nick_name"`                  //用户昵称
			Email        string `json:"email"`                      //邮箱
			AnswerStatus string `json:"answer_status"`              //答主题目状态
			OneStatus    string `json:"one_status"`                 //一审题目状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		if claims.Type == 2 {
			for _, team := range admin.TeamPermissions {
				team_numbers = append(team_numbers, team)
			}
		}

		field := fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email")
		topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//如果是一审项目则需要查答主题目状态
			if project.EnumType == ENUM_TYPE_ONE {
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//如果是二审项目则需要查一审题目状态跟答主题目状态
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,d.`status` one_status ")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' and c.`status` = 1 ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' and c.`status` = 1 ", project.AuditProjectId))
				if utils.StringIsNotEmpty(RequestParams.AnswerStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null "))
				}
				if utils.StringIsNotEmpty(RequestParams.OneStatus) {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("d.status is null "))
				}
				if RequestParams.Status != -1 {
					topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("c.status is null and d.status is null and tas_system_topic.status = %d", RequestParams.Status))
				}
			} else {
				if RequestParams.Status != -1 {
					//查询答主已完成题目排除返修中的
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and (tas_system_topic.reject_time is null or tas_system_topic.reject_time < now())", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				RequestParams.TopicIds = append(RequestParams.TopicIds, topic.Id)
			}
		}*/

		type SystemTopic struct {
			dao.SystemTopic
			TeamNumber     string    `json:"team_number"`                //团队编号
			UserId         string    `json:"user_id" gorm:"uniqueIndex"` //用户Id
			RealName       string    `json:"real_name"`                  // 姓名
			Phone          string    `json:"phone"`                      //手机号
			NickName       string    `json:"nick_name"`                  //用户昵称
			Email          string    `json:"email"`                      //邮箱
			AnswerStatus   string    `json:"answer_status"`              //答主题目状态
			RejectTime     time.Time `json:"reject_time"`                //驳回时间
			OneStatus      string    `json:"one_status"`                 //一审题目状态
			OneAuditStatus string    `json:"one_audit_status"`           //一审审核状态
			TwoStatus      string    `json:"two_status"`                 //二审题目状态
			TwoAuditStatus string    `json:"two_audit_status"`           //二审审核状态
		}
		var claims services.CustomClaims
		if err := claims.ParseClaims(ctx); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		}
		var common dao.Common[dao.SystemAdmin]
		admin, _ := common.First(map[string]interface{}{"id": claims.Id})

		var topicServe services.CommonService[SystemTopic]
		topicServe.Query = map[string]interface{}{}

		//处理团队权限
		var team_numbers []string
		//if claims.Type == 2 {
		for _, team := range admin.TeamPermissions {
			team_numbers = append(team_numbers, team)
		}
		//}

		var projectServe services.CommonService[dao.SystemProject]
		projectServe.WhereStr = append(projectServe.WhereStr, fmt.Sprintf("project_id = '%v' ", RequestParams.ProjectId))
		field := ""
		if project, err := projectServe.First(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			//一审项目
			if project.EnumType == ENUM_TYPE_ONE {
				//如果有二审
				if utils.StringIsNotEmpty(project.FinalProjectId) {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status,d.status two_status,d.audit_status two_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
				} else {
					//如果没有二审只查答主的
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,tas_system_topic.status one_status,tas_system_topic.audit_status one_audit_status")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				}
				if RequestParams.Status != -1 {
					//一审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status != 0", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//一审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else if project.EnumType == ENUM_TYPE_TWO {
				//二审项目
				field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,c.`status` answer_status,c.reject_time,d.`status` one_status,d.audit_status one_audit_status,tas_system_topic.`status` two_status,tas_system_topic.audit_status two_audit_status")
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.WorkProjectId))
				topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.AuditProjectId))
				if RequestParams.Status != -1 {
					//二审通过
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.audit_status = 2", RequestParams.Status))
					} else if RequestParams.Status == 8 {
						//二审拒绝
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = 1 and tas_system_topic.audit_status = 0"))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d", RequestParams.Status))
					}
				}
			} else {
				//答主项目
				//如果有一审
				if utils.StringIsNotEmpty(project.AuditProjectId) {
					//如果有二审
					if utils.StringIsNotEmpty(project.AuditProjectId) {
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status,d.`status` two_status,d.audit_status two_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic d on tas_system_topic.topic_id = d.topic_id and d.project_id = '%v' ", project.FinalProjectId))
					} else {
						//没有二审只有一审
						field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time,c.`status` one_status,c.audit_status one_audit_status")
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
						topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("LEFT JOIN tas_system_topic c on tas_system_topic.topic_id = c.topic_id and c.project_id = '%v' ", project.AuditProjectId))
					}
				} else {
					field = fmt.Sprintf("tas_system_topic.*,tas_system_user.user_id,tas_system_user.real_name,tas_system_user.phone,tas_system_user.team_number,tas_system_user.nick_name,tas_system_user.email,tas_system_topic.`status` answer_status,tas_system_topic.reject_time")
					topicServe.LeftJoin = append(topicServe.LeftJoin, fmt.Sprintf("left join tas_system_user on receiver_id = tas_system_user.user_id"))
				}
				if RequestParams.Status != -1 {
					if RequestParams.Status == 1 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d and tas_system_topic.reject_time < now()", RequestParams.Status))
					} else if RequestParams.Status == 4 {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d or (tas_system_topic.status = 1 and tas_system_topic.reject_time > now())", RequestParams.Status))
					} else {
						topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.status = %d ", RequestParams.Status))
					}
				}
			}
		}
		if len(team_numbers) > 0 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number IN ('%s')", strings.Join(team_numbers, "','")))
		}
		if RequestParams.Title != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.title LIKE '%%%v%%'", RequestParams.Title))
		}
		if RequestParams.TopicId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.topic_id LIKE '%%%v%%'", RequestParams.TopicId))
		}
		if RequestParams.TeamNumber != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.team_number LIKE '%%%v%%'", RequestParams.TeamNumber))
		}
		if RequestParams.NickName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.nick_name LIKE '%%%v%%'", RequestParams.NickName))
		}
		if RequestParams.RealName != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.real_name LIKE '%%%v%%'", RequestParams.RealName))
		}
		if RequestParams.UserId != "" {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_user.user_id LIKE '%%%v%%'", RequestParams.UserId))
		}
		topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.project_id = '%s'", RequestParams.ProjectId))
		if len(RequestParams.EffectiveTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.effective_time BETWEEN '%s' AND '%s'", RequestParams.EffectiveTime[0], RequestParams.EffectiveTime[1]))
		}
		if len(RequestParams.EndDateTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.end_date_time BETWEEN '%s' AND '%s'", RequestParams.EndDateTime[0], RequestParams.EndDateTime[1]))
		}
		if len(RequestParams.FinishTime) > 1 {
			topicServe.WhereStr = append(topicServe.WhereStr, fmt.Sprintf("tas_system_topic.finish_time BETWEEN '%s' AND '%s'", RequestParams.FinishTime[0], RequestParams.FinishTime[1]))
		}
		topicServe.Order = "tas_system_topic.sn"
		topicServe.SelectField = &field
		topicServe.PageSize = -1

		if res, err := topicServe.SelectList(); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			for _, topic := range res.Data {
				RequestParams.TopicIds = append(RequestParams.TopicIds, topic.Id)
			}
		}
	}

	var topicAnswerServer services.TopicAnswerService
	ExportData, err := topicAnswerServer.ExportAnswerNew(RequestParams.TopicIds, RequestParams.ProjectIds)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var projectDao dao.Common[dao.SystemProject]
	project, err := projectDao.First(map[string]interface{}{"project_id": RequestParams.ProjectId})
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	exportFile := excelize.NewFile()
	style, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#8ED3F5", "#8ED3F5"}, Shading: 1},
	})
	style1, _ := exportFile.NewStyle(&excelize.Style{
		Fill: excelize.Fill{Type: "gradient", Color: []string{"#F1B735", "#F1B735"}, Shading: 1},
	})
	//创建工作表行数
	var excel = make(map[string][]interface{}, 0)
	//比较表头的长度
	var excelHeader = make(map[string]int, 0)
	titles := []string{"项目ID", "发题日期", "题目序号", "题目ID", "题目名称", "题目检索标签(如不填写，则默认搜可搜素题目名字)", "题目生效时间", "截止时间", "备注", "题目状态", "一审状态", "二审状态", "操作时间", "审核老师用户ID", "审核昵称", "审核姓名", "审核团队编号", "审核手机号", "审核邮箱", "放弃原因", "开启答主权限", "关闭答主权限", "领取与放弃/上限增加", "领取与放弃/上限减少"}
	//删除默认工作表
	for _, datum := range ExportData {
		sheetsTitle := titles
		//处理表头
		colNameDefault := generateColName(24)
		var rowsData []interface{}
		rowsData = append(rowsData, datum.ProjectId)
		rowsData = append(rowsData, datum.PushTopicDate.Format(timehandler.FormatLayoutDate))
		rowsData = append(rowsData, datum.SN)
		rowsData = append(rowsData, datum.TopicId)
		rowsData = append(rowsData, datum.TopicTitle)
		rowsData = append(rowsData, datum.Labels)
		rowsData = append(rowsData, datum.EffectiveTime.Format(timehandler.FormatLayoutTime))
		rowsData = append(rowsData, datum.EndDateTime.Format(timehandler.FormatLayoutTime))
		if note, err := topicAnswerServer.GetTopicNoteInfo(datum.SystemTopicId); err == nil {
			rowsData = append(rowsData, note)
		} else {
			rowsData = append(rowsData, "")
		}
		workProjectId := ""
		auditProjectId := ""
		finalProjectId := ""
		if project.EnumType == modelbase.WorkProj {
			workProjectId = project.ProjectId
			auditProjectId = project.AuditProjectId
			finalProjectId = project.FinalProjectId
		} else if project.EnumType == modelbase.AuditProj {
			workProjectId = project.WorkProjectId
			auditProjectId = project.ProjectId
			finalProjectId = project.FinalProjectId
		} else if project.EnumType == modelbase.FinalProj {
			workProjectId = project.WorkProjectId
			auditProjectId = project.AuditProjectId
			finalProjectId = project.ProjectId
		}
		if res, err := topicAnswerServer.GetTopicStatusInfo(datum.TopicId, workProjectId, auditProjectId, finalProjectId, project.EnumType); err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			workStatus := ""
			if utils.StringIsNotEmpty(res.AnswerStatus) {
				if res.AnswerStatus == "0" {
					workStatus = "未生效"
				} else if res.AnswerStatus == "1" {
					if res.RejectTime.After(time.Now()) {
						workStatus = "返修中"
					} else {
						workStatus = "已完成"
					}
				} else if res.AnswerStatus == "2" {
					workStatus = "已领取"
				} else if res.AnswerStatus == "3" {
					workStatus = "指派中"
				} else if res.AnswerStatus == "4" {
					workStatus = "返修中"
				} else if res.AnswerStatus == "5" {
					workStatus = "闲置中"
				} else if res.AnswerStatus == "6" {
					workStatus = "已作废"
				} else if res.AnswerStatus == "7" {
					workStatus = "已失效"
				}
				rowsData = append(rowsData, workStatus)
			} else {
				rowsData = append(rowsData, "")
			}

			if utils.StringIsNotEmpty(res.OneStatus) {
				oneStatus := ""
				if res.OneStatus == "0" {
					oneStatus = "未生效"
				} else if res.OneStatus == "1" {
					if res.OneAuditStatus != "0" {
						oneStatus = "审核通过"
					} else {
						oneStatus = "审核拒绝"
					}
				} else if res.OneStatus == "2" {
					oneStatus = "已领取"
				} else if res.OneStatus == "3" {
					oneStatus = "指派中"
				} else if res.OneStatus == "4" {
					oneStatus = "返修中"
				} else if res.OneStatus == "5" {
					oneStatus = "闲置中"
				} else if res.OneStatus == "6" {
					oneStatus = "已作废"
				} else if res.OneStatus == "7" {
					oneStatus = "已失效"
				}
				rowsData = append(rowsData, oneStatus)
			} else {
				rowsData = append(rowsData, "")
			}

			if utils.StringIsNotEmpty(res.TwoStatus) {
				twoStatus := ""
				if res.OneStatus == "0" {
					twoStatus = "未生效"
				} else if res.OneStatus == "1" {
					if res.OneAuditStatus == "2" {
						twoStatus = "审核通过"
					} else {
						twoStatus = "审核拒绝"
					}
				} else if res.OneStatus == "2" {
					twoStatus = "已领取"
				} else if res.OneStatus == "3" {
					twoStatus = "指派中"
				} else if res.OneStatus == "4" {
					twoStatus = "返修中"
				} else if res.OneStatus == "5" {
					twoStatus = "闲置中"
				} else if res.OneStatus == "6" {
					twoStatus = "已作废"
				} else if res.OneStatus == "7" {
					twoStatus = "已失效"
				}
				rowsData = append(rowsData, twoStatus)
			} else {
				rowsData = append(rowsData, "")
			}
		}
		/*topicStatus := ""
		if datum.Status == 0 {
			topicStatus = "未生效"
		} else if datum.Status == 1 {
			//如果是一审项目
			if projectInfo.EnumType == modelbase.AuditProj {
				if datum.AuditStatus == modelbase.FirstAuditPass {
					topicStatus = "审核通过"
				} else {
					topicStatus = "审核不通过"
				}
			}
		} else if datum.Status == 2 {
			topicStatus = "已领取"
		} else if datum.Status == 3 {
			topicStatus = "指派中"
		} else if datum.Status == 4 {
			topicStatus = "返修中"
		} else if datum.Status == 5 {
			topicStatus = "闲置中"
		} else if datum.Status == 6 {
			topicStatus = "已作废"
		} else if datum.Status == 7 {
			topicStatus = "已失效"
		}
		rowsData = append(rowsData, topicStatus)*/
		//操作时间
		rowsData = append(rowsData, datum.UpdatedAt.Format(timehandler.FormatLayoutTime))
		//答主老师用户ID
		rowsData = append(rowsData, "")
		rowsData = append(rowsData, datum.NickName)
		rowsData = append(rowsData, datum.RealName)
		rowsData = append(rowsData, datum.TeamNumber)
		rowsData = append(rowsData, datum.Phone)
		rowsData = append(rowsData, datum.Email)
		if reason, err := topicAnswerServer.GetGiveUpReason(datum.SystemTopicId); err == nil {
			rowsData = append(rowsData, reason)
		} else {
			rowsData = append(rowsData, "")
		}
		rowsData = append(rowsData, project.OpenPerm)
		rowsData = append(rowsData, project.ClosePerm)
		rowsData = append(rowsData, "")
		rowsData = append(rowsData, "")

		sheet := fmt.Sprintf("%s_%s", datum.ProjectId, datum.BatchId)
		excel[sheet] = append(excel[sheet], rowsData)
		exportFile.NewSheet(sheet)

		var answerList []interface{}
		if answerListQuery, err := topicAnswerServer.GetTopicAnswerInfo(datum.SystemTopicId); err == nil {
			if len(answerListQuery) > 0 {
				for i, a := range answerListQuery {
					sheetsTitle = append(sheetsTitle, fmt.Sprintf("提交内容-%v %v-%v", i+1, a.Title, a.Tooltip))
					if a.AnswerType == 0 || a.AnswerType == 1 {
						answerList = append(answerList, a.Content)
					} else {
						answerList = append(answerList, a.ContentUrl+" "+a.FileUrl)
					}
				}
			}
		}

		rowsData = append(rowsData, answerList...)
		startName := generateColName(len(titles) + 1)
		endName := generateColName(len(titles) + len(answerList))
		exportFile.SetCellStyle(sheet, "A1", colNameDefault+"1", style)
		exportFile.SetCellStyle(sheet, startName+"1", endName+"1", style1)
		//插入表头
		if _, ok := excelHeader[sheet]; ok {
			if excelHeader[sheet] < len(sheetsTitle) {
				exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
				excelHeader[sheet] = len(sheetsTitle)
			}
		} else {
			exportFile.SetSheetRow(sheet, "A1", &sheetsTitle)
			excelHeader[sheet] = len(sheetsTitle)
		}
		//插入内容
		exportFile.SetSheetRow(sheet, fmt.Sprintf("A+%d", len(excel[sheet])+1), &rowsData)
	}
	exportFile.DeleteSheet("Sheet1")
	unix := time.Now().UnixNano()
	tempFilename := fmt.Sprintf("./export/topic_answer_%d.xlsx", unix)
	if err := exportFile.SaveAs(tempFilename); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	defer exportFile.Close()
	//删除本地临时文件
	defer os.Remove(tempFilename)
	bucketClient := oss.BucketClient{}
	readFile, _ := ioutil.ReadFile(fmt.Sprintf("./export/topic_answer_%d.xlsx", unix))
	bucketClient.UpBytes(readFile, fmt.Sprintf("task-assign/answer/export/topic_answer_%d.xlsx", unix))
	ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/task-assign/answer/export/topic_answer_%d.xlsx", utils.ServerConf.AliOssConf.CallBackHost, unix)})
	return
}

type QueryTopicUserRecordRequest struct {
	/*Page      int64  `json:"page"`
	PageSize  int64  `json:"page_size"`*/
	ProjectId string `json:"project_id"`
	TopicId   string `json:"topic_id"`
}

func QueryTopicUserRecordHandler(ctx iris.Context) {
	var RequestParams QueryTopicUserRecordRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	type TopicUserRecord struct {
		dao.TopicUserRecord
		RealName string `json:"real_name"`
		NickName string `json:"nick_name"`
		EnumType int    `json:"enum_type"`
	}
	var topicUserRecordServe services.CommonService[TopicUserRecord]
	field := "tas_topic_user_record.*,b.real_name,b.nick_name,c.enum_type"
	topicUserRecordServe.SelectField = &field
	/*topicUserRecordServe.Page = RequestParams.Page
	topicUserRecordServe.PageSize = RequestParams.PageSize*/
	topicUserRecordServe.PageSize = -1
	topicUserRecordServe.LeftJoin = append(topicUserRecordServe.LeftJoin, fmt.Sprintf("left join tas_system_user b on tas_topic_user_record.user_id = b.user_id"))
	topicUserRecordServe.LeftJoin = append(topicUserRecordServe.LeftJoin, fmt.Sprintf("left join tas_system_project c on tas_topic_user_record.project_id = c.project_id"))
	if utils.StringIsNotEmpty(RequestParams.ProjectId) {
		topicUserRecordServe.WhereStr = append(topicUserRecordServe.WhereStr, fmt.Sprintf("tas_topic_user_record.project_id = '%v'", RequestParams.ProjectId))
	}
	if utils.StringIsNotEmpty(RequestParams.TopicId) {
		topicUserRecordServe.WhereStr = append(topicUserRecordServe.WhereStr, fmt.Sprintf("tas_topic_user_record.topic_id = '%v'", RequestParams.TopicId))
	}
	if res, err := topicUserRecordServe.SelectList(); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: iris.Map{"count": res.Total, "list": res.Data}})
		return
	}
}
